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} %>
Related
On my Home#Index page, I have this:
<%= render 'home/popular_products', :collection => #products, :as => :product %>
In my Home#_popular_products view, I have this:
<div class="span2 recommended">
<%= image_tag product.image_url(:thumb).to_s %>
</div>
This is the error I keep getting:
undefined local variable or method `product' for #<#<Class:0x007f871c4f6848>:0x007f871cdb7e28>
As far as I understand it, I shouldn't even have to specify the :as attribute in my render statement - but I tried this to be explicit after just using the :collection => #products wouldn't work.
In my Home#Index Controller I have this:
#products = Product.all.sample(6)
Thoughts?
I believe you have to specify the :partial option if you want to pass in any other options. Ie:
<%= render :partial => 'home/popular_products', :collection => #products, :as => :product %>
Should work.
Do you put _popular_products.html.erb file in your app/views/home/? I think you're using partial not following convention of rails, so rails's not understood product variable. Your partial should be named _product.html.erb if you want to used like that. With that partial, you can write like this:
<%= render #products %>
Update
Solution 1
Index page:
<%= render 'popular_products', :collection => #products %>
Partial:
<%= image_tag popular_products.image_url(:thumb).to_s %>
Solution 2
Index page:
<% #products.each do |product| %>
<%= render :partial => "popular_products", :locals => { :product => product } %>
<% end %>
Partial:
<%= image_tag product.image_url(:thumb).to_s %>
Here is the code in rfqs/_form_new.html.erb to add a selection box for standard.
<%= simple_form_for #rfq do |f| %>
<div id="std">
<%= render :partial => 'standards/standards', :collection => #rfq.standards, :locals => { :f => f } %>
</div>
<%= link_to_function "Add Std", nil do |page| %>
page.insert_html :bottom, :std, :partial => 'standards/standards'
<% end %>
<% end %>
The html source code has # after href and cause no reaction for clicking the link.
Add Std
The _standards.html.erb partial looks like:
<%= f.association :standards, :collection => Standard.active_std.all(:order => 'name'), :label_method => :name, :value_method => :id %>
Any thoughts about missing link after href? Thanks.
I don't believe 3.1's link_to_function works the same way as older versions; I don't see anything in the source that utilizes a block.
This seems in keeping with using unobtrusive JavaScript. The Rails pulls related to accepting a block seem more related to link text rather than injecting JS.
In my new.html.erb page, i use the following line to render a partial and it works fine.
<%= render :partial => "submissions/player_form", :locals => { :submission => #submission } %>
Now i want to render exactly the same partial via RJS
<p>Player Type: <%= f.select(:PLAYER_TYPE, $playersList, {:prompt => 'Select the Player Type'} %></p>
<%= observe_field("submission_PLAYER_TYPE", :frequency => 1,
:url => { :controller => 'submissions',
:action => :display_player_form },
:with => "'player='+value") %>
display_player_form.rjs:
page.replace_html 'observed_assay_form', :partial => 'submissions/player_form', :locals => {:submission => #submission }
Nothing is displayed!!
Am i missing something??
Thanks for helping me out with this :)
I finally figured it out. So here are my findings:
In the partial, include the form_for tag, just like in the original form--
<% form_for #object do |f| %>
In the action used when observing the field, in my case, 'display_player_form', create a new instance of the object(see below)
#object = Object.new
In your rjs file, enter the following:
page['id of div'].replace_html :partial => 'your_partial_name'
There you go...
Hope this helps
I would rename display_player_form.rjs to display_player_form.js.erb and have its contents look like this:
$("#observed_essay_form").html('<%=
escape_javascript(
render :partial => 'submissions/player_form', :locals => {:submission => #submission }
)
-%>');
$("img[src$='spinner.gif']:visible").hide(); // optional - hide any visible spinner.gif images
I use jQuery, not Prototype, by the way.
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"
Here is a simple example of the problem.
http://gist.github.com/235729
In short, if you have a index.rhtml with:
<%= link_to_function "A link to insert a partial with nested insert_html" do |page|
page.insert_html :top, :with_a_nested_insert_html, :partial => 'example_partial_with_nested_insert_html'
end %>
And a _example_partial_with_nested_insert_html.rhtml
<%= link_to_function "A nested link to insert_html" do |page|
page.insert_html :top, :with_a_nested_insert_html, :partial => 'you_wont_see_this'
end %>
It breaks the "A link to insert a partial with nested insert_html". I am thinking something needs to be done to protect the javascript in the partial.
Any thoughts?
Here's how I do it.
<%= link_to_function( "insert it", :id => 'foo') do |page|
partial = escape_javascript(render :partial => "my_partial", :object => Object.new)
page << "$('#my_div').append(\"#{partial}\")"
end %>
Try using escape_javascript before rendering the partials - see this other question.
I didn't try but I strongly think the syntax should be more something like :
<% link_to_function "A link to insert a partial with nested insert_html" do |page|
<%= page.insert_html :top, :with_a_nested_insert_html, :partial => 'example_partial_with_nested_insert_html' %>
<% end %>