How to use a partial layout with a collection? Rails - ruby-on-rails

I am calling:
render #users, :layout => "homepage"
because I want to wrap the default partial for users (views/_user.html.erb) with a custom layout just for the homepage (views/users/_homepage.html.erb).
but, when I do this, I get the NoMethodError on the user.name method.
For some reason it seems like the user variable is not getting initialized properly inside the user partial.
It turns out after some test, the homepage partial is not even getting called, it is going straight to the user partial ....

This is not the solution I wanted, I believe there may actually be a way to make this work using just a call to render, but this is what gave me the correct output:
#users.each do |user|
render :partial => "users/user",
:layout => "users/homepage",
:locals => { :user => user }
end
Or is it that the :layout option only works when rendering a single resource and not a collection?

As of Sept. 2019, in Rails 6, this is how we are doing this:
<%= render partial: 'homepage_user_list_entry', collection: #users %>
With alias:
<%= render partial: 'homepage_user_list_entry', collection: #banned_users, as: :user %>
Hope this helps future searchers, and also me in the future.

Try adding :as => :user to render a partial from a view:
<%= render :collection => #users, :as => :user, :partial => 'users/user_short_form', %>

You should do something like
<%= render 'homepage', :collection => #users, :layout => 'homepage' %>
not sure about the :layout option, but you have to pass #users thro :collection
hope it helps!

Not sure if this is a newer addition to Rails, but in Rails 4.2.1 I can pass my collection to the partial argument of render:
render partial: #users, layout: "homepage"

Related

Issue working with partial in rails

I am using rails 3.1. I have a view products/show.html.erb and I call a partial like this
<%= render 'productrelationships/relatedproduct',:collection => #product.relatedproducts %>
and i access it in this way inside my partial (productrelationship/_relatedproduct)
<% logger.error 'Related Products ' + relatedproduct.inspect %>
The inspect returns a nil. But if I try the same inside my show.html.erb, it is not nil. There is some mistake in passing the value. What am I doing wrong?
Found the answer. It started working when i added :partial while rendering
<%= render :partial => 'productrelationships/relatedproduct',:collection => #product.relatedproducts %>
Need to specify the local variable.
<%= render :partial => 'productrelationships/relatedproduct',
:collection => #product.relatedproducts,
:as => :relatedproduct %>

Can you render a single instance of an object through a partial using collections?

So for example, if I have a partial that works with #users as a collection, i.e.
<%= render :partial => 'dashboard/dashboard_pane', :collection => #users %>
where
#users = User.all
But DOESNT seem to work with a single instance
<%= render :partial => 'dashboard/dashboard_pane', :collection => #user %>
where
#user = User.first
The questions is, why?
I guess it's looping an Array.
Try with:
[ User.first ]
To use this partial with a single object, you should't be calling it with :collection. Try this instead:
<%= render :partial => 'dashboard/dashboard_pane', :object => #users.first %>
I think the answer is because it's not a collection :)
As #apneadiving said try putting it in an array. A very contrived alternative is to make it into a bona fide collection:
#users = User.find_all_by_id(#user.id)
I wouldn't recommend this though.

Rails How to Render a Partial

I currently am able to render a partial in JS like so:
$("#cmtList_<%= #commentable.id %>").prepend("<%=escape_javascript(render :partial =>"comments/comment", :locals => {:comment => #comment})%>");
The above works swell for rendering/returning one new comment.
Now I want to reuse that same partial(to stay DRY), but be able to pass an array of comments as #Comments, and have Rails loop through all the #comments records (1 or more) using the same partial, I tried this but it errors:
$("#cmtList_<%= #commentable.id %>").prepend("<%=escape_javascript(render :partial => "comments/comment", :collection => {:comment => #comments})%>");
Any ideas?
Thanks
Try this inside of escape_javascript:
render :partial => "comments/comment", :collection => #comments
Docs say that this should work too (too much magic for me):
render #comments
Check "3.4.5 Rendering Collections" from here:
http://guides.rubyonrails.org/layouts_and_rendering.html
Try:
$("#cmtList_<%= #commentable.id %>").prepend("<%=escape_javascript(render :partial => "comments/comment", :collection => #comments)%>");
which will look for a local variable "comment".
For more info: http://guides.rubyonrails.org/layouts_and_rendering.html

What does "render #collection" do?

I'm trying to learn Rails better by looking at example applications, and while looking at this line of the source of railscasts.com, I noticed it does this:
<div class="episodes">
<%= render #episodes %>
</div>
What exactly is going on here? Why isn't this documented on the render function? Or is it?
This is a handy shortcut for doing
<%= render :partial => "episode", :collection => #episodes %>
which is another way of doing
<% for episode in #episodes do %>
<%= render :partial => "episode", :locals => { :episode => episode }
<% end %>
which is pretty obvious in what it does :)
Hope that makes sense :)
btw it's really surprising I couldn't find the docs for this too.
This is shorthand for
render :partial => "episode", :collection => #episodes
The form above is documented in the Rails API docs under render (ActionController::Base). The shorthand form is not documented as far as I can see except in the Rails Guides.
This is a new shortcut:
<%= render #episodes %>
# equivalent to
<%= render :partial => 'episode', :collection => #episodes %>
You can also do shortcuts with single items
<%= render 'comment', comment => #comment %>
# equivalent to
<%= render :partial => 'comment', :locals => {:comment => #comment} %>

Rails partial locals not persisting when sent to another partial as its own local

I render a partial like so:
<%= render :partial => 'widgets/some_partial, :locals => {:foo => 'bar'} %>
So inside of _some_partial.html.erb I render two more partials like so:
<% #foo.nil? #=> false %>
<%= render :partial => 'widgets/another_partial', :locals => {:foo => foo} %>
`<%= render :partial => 'widgets/another_partial_again', :locals => {:foo => foo} %>`
The foo local variable renders fine in some_partial.html.erb and even in another_partial_again.html.erb. However, the foo variable is inaccessible in another_partial.html.erb even though I explicitly passed it in the render call.
What is happening here?
Thanks for the help.
I had the undefined local variable or method error come up for me too when I was rendering a partial with :locals defined.
However, I had a different issue causing my problem, so I thought I would share my solution in case it helps anyone else. (This page was the first result when I googled this error after all)
Basically just make sure you use :partial => 'path/to/partial' in your call to render.
I.e.
<%= render :partial => 'widgets/some_partial', :locals => {:foo => 'bar'} %>
NOT like I was doing:
<%= render 'widgets/some_partial', :locals => {:foo => 'bar'} %>
Easy for a rails/ruby newbie like me to miss.
Solved. Turns out I was also rendering the same partial from the controller without sending the proper local variables. Thanks anyways!!!
Bumped into this very old question cause I faced the same issue.
Turned out that with Rails 4+ if you are not using collections or layout the correct way is:
# Instead of <%= render partial: "account", locals: { account: #buyer } %>
<%= render "account", account: #buyer %>
As documented here.

Resources