rails: Layout can no longer access local variables
Steps to reproduce
After upgrading from Rails 5.0.6 to Rails 5.1.4 I am no longer able to render locals to a layout. Rendering to a template still works.
controllers/users_controller.rb
class UsersController < ApplicationController
layout 'application'
def index
render locals: { user_name: 'John' }
end
end
views/layouts/application.html.erb
...
<%= user_name %>
...
views/users/index.html.erb
...
<%= user_name %>
...
Expected behavior
Expected behavior is user_name appears in both the layout and the index template.
Actual behavior
ActionView::Template::Error: undefined local variable or method 'user_name'
is raised by layout.
System configuration
Rails version: 5.1.4
Ruby version: 2.4.2
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 11
- Comments: 20 (8 by maintainers)
Confirm this is issue in Rails 5.2.2 as well, specifically when attempting to render outside of a controller, for example generating PDF reports from a background job.
Where report_name local is used in the layout, will fail with ActionView::Template::Error: undefined local variable or method `report_name’
Just to highlight something very important @cmcguff said, which I missed the first time around until I finally saw it in my own rspec specs, if a local named :foo is used in the layout file the ActionView::Template::Error occurs; but if you use local_assigns[:foo] in the layout, that works.
So local_assigns is not required in the template file, but is required for variables used in the layout file.
+1 for a permanent fix for this. I can also confirm this is an issue in 5.1.4 + 5.1.6
To add…
With a partial:
_example.html.erb
This doesn’t work:
show.html.erb
But this works:
Using
local_assigns
works as well, but it feels like a step backwards if that’s the new norm.Any news? It still doesn’t work on Rails 5.1.6.1
@composerinteralia I don’t follow — d6bac046922fcee05366d26d75349dde70d25f6b looks like a performance optimisation for looking up the layout, with no suggestion that it should affect the behaviour. Perhaps @tenderlove can confirm or deny that the behaviour change is intentional?
I was able to recreate this as well. I can look into it. In the meantime I think you can use
local_assigns[:user_name]
as a workaround.Getting this in 5.2.1 What’s the status?
Based on d6bac04 I believe this is the intended behavior. If so, it is probably worth adding to the documentation.