Home > Mobile >  Rails failing to serve erb based templates from /public in development env
Rails failing to serve erb based templates from /public in development env

Time:09-16

This is bugging me just because it seems like it shouldn't be that hard to debug but I cannot figure out what is going on.

We have a 404 page at <app_root>/public/404.html.erb

We then have some custom logic for handling 404s in our application controller

  def render_404
    if request.format.json?
      render({
        json:   {message: "Not found: /#{params[:path]}"},
        status: :not_found
      })
    else
      @fail_photo = Photo.find_by(name: "programmatic_404_image")

      render({
        file:   Rails.root.join("public", "404.html.erb"),
        layout: false,
        status: :not_found
      })
    end
  end

This works in production but in development it wraps the whole thing in a <pre> tag and renders the html as raw text. I can fix this by changing to layout: true and removing the .erb extension from the file. Obviously the erb is no longer processed but it now serves everything else.

I've looked throuhg the environment files in config for settings that could be affecting this but haven't come up with anything. Any thoughts?

CodePudding user response:

Don't put your erb templates in /public to begin with. The only reason Rails places the default error pages there is that the default error handler just redirects to a static file. There is no reason you should ever put anything that cannot be served straight by the web server (apache, nginx) in the /public directory.

You also want to to be careful what you toss into your application controller as you're putting that code into every controller in your application.

Instead create a seperate controller and just place your views like you normally would (app/views/errors):

class ErrorsController < ApplicationController
  def not_found
    respond_to do |format|
      format.json { head :not_found } 
      format.html { render "404", status: :not_found }
    end
  end
end
Rails.application.routes.draw do
  ...
  match "/404", to: "errors#not_found", via: :all
  ...
end
module YourAppName
  class Application < Rails::Application
    # ...
    config.exceptions_app = self.routes # Add this line
  end
end

The handling of error pages is controlled by config.consider_all_requests_local. In development it defaults to true and displays those helpful error pages for debugging so you need to set it to false in config/environments/development.rb to actually see your custom error pages.

CodePudding user response:

Public directory expects static pages to be put, some thing which is interacting the ruby code should not be there. You can make a Error controller, I do not get the use of

@fail_photo = Photo.find_by(name: "programmatic_404_image")

If you want to show it in view, you can redirect to a page where 404 image will be hard-coded. Better to put this image either in public or any s3 bucket, and serve it from there. No need to put in a DB with url. At least we should not request DB for serving a single image.

  • Related