Understanding Rails “magic” with regards to rendering partials (and passing locals into them).
Why does this work:
<%= render "rabbits/form" %>
And this work:
<%= render "rabbits/form", :parent => @warren, :flash => flash %>
but this does not work:
<%= render "rabbits/form", :locals => { :parent => @warren, :flash => flash } %>
But this does:
<%= render :partial =>"rabbits/form", :locals => { :parent => @warren, :flash => flash } %>
Also, how can I look up these nuances so I don’t need to bother people on S.O.?
The short answer is the render method looks at the first argument you pass in. If you pass in a hash (which includes
:partial => 'foo', :locals => {blah blah blah}) then it will pass in all of your arguments as a hash and parse them accordingly.If you pass in a string as your first argument, it assumes the first argument is your partial name, and will pass the remainder as your locals. However, in that subsequent call, it actually assigns
:locals => your_locals_argument, which in this case is the entire:locals => {locals hash}, instead of just{locals hash}; i.e. you end up with:locals => {:locals => {locals hash}}, rather than:locals => {locals hash}.So my advice is just to always explicitly pass values the same way all the time, and you won’t have problems. In order to learn about this, I went directly to the code itself (actionpack/lib/base.rb,
render()method in Rails 2; Rails 3 is different). It’s a good exercise.Furthermore, don’t worry about “bothering” people on SO. That’s why this site exists. I even learned something from this.