2

I'd like to use Rails's asset pipeline to compile our custom HTTP error pages for nginx. I'd also like to use the standard Rails convention of a layout (say, app/views/layouts/error.html.erb) and views that render within that layout.

I found one article describing a way to simply precompile some ERb templates, but I'd still end up copying most of the layout code between the various templates.

I also thought about using caches_page in a controller and simply forcing the errors to occur during the build so that the files end up in public, but that seems really hacky.

Is there any way to achieve this?

4

1 回答 1

4

I ended up going the hacky route, which wasn't as hacky as I thought.

Basically, I created a controller, routes, and templates for the errors I plan to handle:

# config/routes.rb
resources :errors, only: :show

# app/controllers/errors_controller.rb
class ErrorsController < ApplicationController
  layout 'errors'

  # you may need to disable various filters
  skip_before_filter :authenticate_user!

  # cache full versions of the pages we generate
  caches_page :show

  def show
    render action: params[:id]
  end
end

# app/views/errors/404.html.erb and so on
<p>404 Not Found</p>

Then I created a Rake task to "visit" each of these pages, which will cause the controller to cache the page in /public/errors:

task :create_error_pages => :environment do
  session = ActionDispatch::Integration::Session.new(Rails.application)

  %w{401 404 422 ...}.each do |error|
    session.get("/errors/#{error}")
  end
end

Now during deploy, I run this:

RAILS_ENV=production bundle exec rake assets:precompile create_error_pages

to generate our static HTTP error pages.

This will work in any environment where config.action_controller.perform_caching = true. This is on by default in production, but not in development, so be aware.

于 2012-10-18T01:17:57.663 回答