Rails 5 -> 6 Upgrade: Fixing render file occurrences

We recently upgraded a Rails 5 app to Rails 6 (the Rails 7 upgrade is soon to follow) and discovered render file no longer works with erb files. The app was using render file to display a custom 401 error page, with dynamic content:

1
render file: 'public/401.html', status: :unauthorized

Previously, Rails mapped 'public/401.html' to our public/401.html.erb file, and rendered it correctly. In Rails 6 and 7, it no longer works.

Custom error page

To fix it, we re-wrote the code as a custom view/controller. We added a new ErrorsController with an unauthorized action:

1
2
3
4
5
class ErrorsController < ApplicationController
  def unauthorized
    render status: :unauthorized
  end
end

We added a route for it, so that whenever Rails renders /401 it uses our new custom controller/action:

1
get '/401', to: 'error#unauthorized', as: :unauthorized

Lastly, we renamed public/401.html.erb to app/views/errors/unauthorized.html.erb so that the view name matches our controller/action.

Now, whenever our Rails app returns a 401, it will correctly render the content from app/views/errors/unauthorized.html.erb.

Notes

Here’s the Rails commit that changed the behaviour of render file, if you’d like to read more - https://github.com/rails/rails/commit/c7820d8124c854760a4d288334f185de2fb99446