What is the difference between render :object and :collection? - ruby-on-rails

Is it
#cart have to put in :object ?
#cart.item have to put in : collection ?

Using :collection will run the partial once for every item in the array. While you're in the partial, the name of the object will be the name of the partial. So if you have:
<%= render :partial => 'cart', :collection => #carts %>
Then in your partial (_cart.html.erb, for example) you can use the cart object:
Cart Name: <%= cart.name %>
Here's a link to the documentation:
http://guides.rubyonrails.org/layouts_and_rendering.html

Related

Why does my render partial call not give me proper access to the local variable?

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 %>

Rails passing form_for object to partial

I would like to pass the form_for object to a partial:
<%= form_for #price do |f| %>
...
<%= render :partial => "price_page", :object => #price, :as => :f %>
...
<% end %>
When I call:
f.radio_button
Brings the error:
undefined method `radio_button' for #<Price:0x3cb1ed0>
How can I use f as I usually would in this partial?
Try passing form object as local
<%= render :partial => "price_page", :locals=>{:f=>f} %>
You can pass form builder object as a local variable like below,
<%= form_for #price do |f| %>
<%= render :partial => "price_page", :locals => { :f => f } %>
<% end %>
in your partial file you will be receiving form builder as a local variable "f", you can use like below,
<% f.radio_button, {} %>
I ran across this question trying to figure out how to get a form builder into a partial without an additional form tag. That's the primary use case I could think of for this question, so I'm adding this answer for future visitors.
To solve my problem, I have my form_for in my layout and I render my partial passing only the model. In my partial I use fields_for.
Looks (something) like this:
= form_for #price do |f|
...
= render partial: "price_page", object: #price, as: 'price %>
...
Then, my partial has this:
= fields_for price do |f|
...

Render partial :collection => #array specify variable name

I am rendering a partial like this:
$("#box_container").html("<%= escape_javascript( render :partial => 'contacts/contact_tile', :collection => #contacts) %>")
Problem is that my partial is expecting the variable 'contact'.
ActionView::Template::Error (undefined local variable or method `contact'
I simply want to tell the partial to expect a variable contact. Should iterate through #contacts as contact. How do I do that?
Found this is also helpful from the docs. You aren't limited to having the variable named after the partial:
http://guides.rubyonrails.org/layouts_and_rendering.html
To use a custom local variable name within the partial, specify the
:as option in the call to the partial:
<%= render :partial => "product", :collection => #products, :as => :item %>
With this change, you can access an instance of the #products collection as the item local variable within the partial."
The documentation at http://guides.rubyonrails.org/layouts_and_rendering.html says:
When a partial is called with a pluralized collection, then the
individual instances of the partial have access to the member of the
collection being rendered via a variable named after the partial.
So it will be passed a variable called "contact_tile" instead of "contact". Perhaps you can just rename your partial.
If this naming is important, you could do it explicitly without the collection option by something like:
#contacts.each { |contact| render :partial => 'contacts/contact_tile', :locals => {:contact => contact } }
(although as a commenter pointed out, this may not be as performant)
Latest syntax are :
index.html.erb
<%= render partial: "product", collection: #products %>
_product.html.erb
<p>Product Name: <%= product.name %></p>
#products is used in partial as product
Where #products can be considered as Product.all
and product can be considered as a row of product i.e. Product.first as looped all product one by one.
You can specify a custom variable name as the default with the keyword as:
<%= render partial: 'line_items/line_item', collection: order.line_items, as: :item %>

How to pass another flag variable in addition to collections to a partial?

How can I pass a is_featured = true to the following partial?
<%= render :partial => 'stores', :collection => #stores %>
I only need to pass the is_featured in one place (in all other places I call the partial as above.
You can use the locals option of render
<%= render :partial => 'stores', :collection => #stores, :locals => { :is_featured => is_featured } %>
In the partial you would access it as a method:
<%= is_featured %>

Multivariable Partial in Ruby on Rails

I have a partial that I want rendered with a collection and another variable. Is it possible to pass more than one variable to a partial?
To illustrate:
Category HABTM Brands
This is just semi-pseudo-code, but I want to do something like:
<% #categories.each do |c| %>
<%= c.name %>
<%= render :partial => "mypartial", :collection => c.brands, :object => c.id %>
<% end %>
The partial needs the category id as well as the "current_brand". Any ideas?
Inside of your view, you pass a hash to the :locals key-value pair in the options hash argument.
<%= render :partial => 'partial', :locals => { :foo => 'a', :bar => 'b' } %>
... and these keys become available as variables in your partials.
Foo is: <%= foo %>
Bar is: <%= bar %>
You can give a partial any number of variables with the :locals option. It takes a hash of variable names and values.

Resources