How to Do Static Content in Rails

How to do static content in Rails?

thoughtbot has a plugin called high_voltage for displaying static content: https://github.com/thoughtbot/high_voltage

How to do static content in Rails?

thoughtbot has a plugin called high_voltage for displaying static content: https://github.com/thoughtbot/high_voltage

Static pages in Rails?

There are a variety of approaches you can take (they're not all good approaches).

1 - public directory

If 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:

  • Because it doesn't have to waste time going through the Rails stack, the client will receive a faster response.

Disadvantages:

  • You won't be able to use your sites layout. Or view helpers like link_to.
  • Instead of your views being in one place (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?

2 - Place in app/views and render directly from the Router

It 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.



3 - Use 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

4 - 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. ↑

5 - 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?

6 - 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.

7 - High Voltage gem

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') %>.

Serving a static file from a specific URL in rails

The easiest method is to place the file in your public directory. By default this serves static assets in most cases.

How does Rails serve static content out of public?

Rails doesn't use Rack::Static, it has its own version, ActionDispatch::Static. You should see it if you run rake middleware.

This is only added to the Rails middleware stack if config.serve_static_assets is true. This setting defaults to true, but the default generated config/environments/production.rb turns if off.

The idea is that during development you have a simple single process that you can run and check everything is working and where performance isn't an issue, but when you deploy to production you configure your webserver (usually Apache or Nginx) to serve the static files as it is much better at that than Ruby.

If you use Heroku, their latest Cedar stack doesn't use a separate webserver for static files, so as part of the deploy process they inject a Rails plugin to serve static assets. All this plugin does is set serve_static_assets to true.

Rails: How to link to static pages

in your routes.rb you should have something like

get '/page', to: 'path#page', as: :page

where path is the folder where the page file is in

eg

get '/page', to: 'layout#page', as: :page

then you will link with

<li><%= link_to "page", page_path %>

Static pages to ruby on rails

Start with a single model and controller for companies. Create a index method inside the app/controllers/companies_controller. Then create the content inside file app/views/companies/index.html.erb to check that everything works, for example:

<h1> Hi! This is root page and index method in CompaniesController! </h1>

In config/routes.rb, you must specify a plural name for companies if you plan to create and process more than one, and leave it as it is, if the entity is the only one company for this project. Set plural name for this resource for this moment to create standard routes for CRUD:

resources :companies
root to: "companies#index"

More about routes you can find in rails guide.
You can try using the built-in scaffold generator in order to quickly generate the application skeleton:

rails generate scaffold companies

The command above will generate controller, model, views and routes with CRUD methods in controller and views for the controller methods. Each view in app/views/"resource_name_plural" adjusted with method in controller in config/routes.rb file. This is how the MVC pattern works.

If you want to create static pages, maybe you should look at the high_voltage gem.



Related Topics



Leave a reply



Submit