So I'm wondering what the best way to do static pages in Rails is, or rather Rails 3. I've always been a little confused about this, like should I create a controller or not?
There are a variety of approaches you can take (they're not all good approaches).
public
directoryIf it's truly static, you can put it in the public
directory. Things in the public
directory will be served immediately, without going through the Rails stack.
Advantages:
Disadvantages:
link_to
.app/views
), now they're in two places (app/views
and public
). This can be confusing.Thoughts: I feel pretty strongly that the disadvantages outweigh the advantages here. If you're looking to make a minor improvement in speed at the expense of readability and programmer happiness, why use Rails in the first place?
app/views
and render directly from the RouterIt is possible to render views from the router. However, it definitely isn't The Rails Way.
From the official RailsGuide on routing:
1 The Purpose of the Rails Router
The Rails router recognizes URLs and dispatches them to a controller's action.
Architecturally, there isn't anything inherently wrong with having a router map directly to a view. Many other frameworks do just that. However, Rails does not do that, and deviating from an established convention is likely to confuse other developers.
like should I create a controller or not?
Unless you want to take one of the approaches mentioned above - yes, you should create a controller.
The question then becomes what to name the controller. This answer outlines some options. I'll list them here with some thoughts. I'll also add three other options.
ApplicationController
# routes.rb get "/about" to: "application#about" # application_controller.rb class ApplicationController < ActionController::Base def about render "/about" end end # app/views/about.html.erb
The advantage here is that you don't introduce overhead/bloat by creating a new controller and folder. The disadvantage is that it's not The Rails Way. Every controller you create inherits from ApplicationController
. ApplicationController
is typically used to house functionality that you want to share between all other controllers. See this example from the Action Controller Overview Rails Guide:
class ApplicationController < ActionController::Base before_action :require_login private def require_login unless logged_in? flash[:error] = "You must be logged in to access this section" redirect_to new_login_url # halts request cycle end end end
StaticController
or StaticPagesController
Michael Hartl's popular Ruby on Rails Tutorial uses a StaticPagesController
. I agree with the source I got this from in that I don't like this approach because the pages often aren't actually static.
Also, there is a possibility of confusion - why did we put other static views in separate controllers? Shouldn't static views be rendered from the StaticPagesController
? I don't think the possibility of confusion is too high, but still wanted to note it.
Also note Hartl's footnote:
Our method for making static pages is probably the simplest, but it’s not the only way. The optimal method really depends on your needs; if you expect a large number of static pages, using a Static Pages controller can get quite cumbersome, but in our sample app we’ll only need a few. If you do need a lot of static pages, take a look at the high_voltage gem. ↑
PagesController
The official Ruby on Rails routing guide uses PagesController
. I think this approach is fine, but it isn't descriptive at all. Everything is a page. What distinguishes these pages from the other pages?
UncategorizedPagesController
I would call the controller UncategorizedPagesController
, because that's exactly what they are - uncategorized pages. Yes, it's a little more cumbersome to type and read. I prefer the advantage of clarity over conciseness, but I could understand the choice to be more concise and go with PagesController
, or something else.
With High Voltage, you don't have to do the tedious work of writing out routes and empty controller actions:
# routes.rb root 'pages#home' get '/about', to: 'pages#about' get '/contact', to: 'pages#contact' get '/help', to: 'pages#help' get '/terms-of-service', to: 'pages#terms_of_service' get '/landing-page', to: 'pages#landing_page' ... # pages_controller.rb def PagesController < ApplicationController def home end def about end def contact end def help end def terms_of_service end def landing_page end ... end
You just add your pages to app/views/pages
and link to them: <%= link_to 'About', page_path('about') %>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With