Rails partial collection empty? - ruby-on-rails

I've been trying to figure this one out for about an hour now. I have a partial collection that is indeed populated with member model objects, and when I try to render it using collection:
<%= render :partial => 'list', :collection => #members %>
In my _list.html.erb the #member_id and #member_email attributes are empty in the rendered html:
<%= check_box_tag('selected_member[]', #member_id, false) %>
<%= #member_email %>
The view renders correctly and I get 3 member items, but with the id and email blank.
What am I doing wrong? If I try to access the partial member using "member_id" or "member.id" I get "undefined local variable or method `member'", so clearly that's not the correct notation.
Now I've seen a bunch of different examples, but the collection method is the way I need to go. I need the partial to only deal with each member as the parent view has support for grouping members in different ways. If I implement a loop in the partial for each member, I'll have to move the grouping view code into it as well, which interacts with input fields in the parent view. e.g. it would be a mess to maintain.
Thanks in advance.

When you do:
<%= render :partial => 'list', :collection => #members %>
Rails is expecting the local variable within the partial file to be named the same as the partial file itself, in this case list.
So instead of member, by default it would be list like this:
<%= check_box_tag('selected_member[]', list.id, false) %>
<%= list.email %>
If you want the local variable to instead be named member, you should either rename the partial file or use this syntax:
<%= render :partial => 'list', :collection => #members, :as => :member %>
More info here (Sec. 3.4.5): http://guides.rubyonrails.org/layouts_and_rendering.html

Related

How to use single html.erb file for multiple actions

I want to create multiple function but each functions render to its data to single file as like simple php, is possible with ruby and rails. I tried to found this but search results are not as per my point of view.
Partials will help you:
Create view than you want show in other views, name it _your_view.html.erb
Include it in other views:
<%= render :partial => 'path/to/your/partial/your_view' %>
Path can be skipped if your partial is in /app/views root folder, not in subfolders.
Don't forget remove first _ symbol from partial name while including (file is _your_view.html.erb and including is your_view).
Also you can pass parameters into partial:
<%= render :partial => 'path/to/your/partial/your_view', :locals => {:param1 => 'value1' } %>
and use them in partial:
<% value = local_assigns[:param1] %>
<%= text_field_tag :param1, :value => value %>
Yes, this is possible. You should look at using custom View helpers. For start, look at these links:
http://www.rails-dev.com/custom-view-helpers-in-rails-4
http://api.rubyonrails.org/classes/ActionView/Helpers.html

rails: render a collection of models using an specific html view

I have the following simple problem with rails.
Let say I have a model User.
In a view, if I do:
<%= render User.all %>
The file view in views/user/_user.html.erb will be called and printed for each of the users.
How can I change this to use an specific view?
I need something like:
<%= render :data=>User.all :template=>"user/_user_2ndview.html"%>
Any help?
Thanks in advance
You can use the collection option:
<%= render :collection => User.all, :partial => "users/user2ndview",
:as => :user %>
The view must be placed in views/users/_user2ndview
See the Rails guides on rendering collections for more details.

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

Using scope with a view partial

I have been using a scope to present some information to show todos that have been completed and are 24 hours old
scope :completed, joins(:user).where(:todos => { :complete => true })
scope :logged, completed.where("todos.updated_at <= ?", 1.day.ago)
Using the regular todo partial
<%= render #user.todos.logged =>
However I want to present those logged items in a different partial _logged.html.erb. I just can't figure out the proper way to pass scope results to a specific partial.
Thanks
Well, if you want to render partial for each item, yo can do:
<%=render :partial=> 'logged', :collection=>#user.todos.logged %>
Or if you want to pass the whole array to one instance then you can do
<%=render :partial=> 'logged', :object=>#user.todos.logged %>
In both cases I guess your object will be called logged.
Assuming that your partial contains <%= logged.title %> you want to render for each item, so you can use the first version.
First, to keep my conscience clean, let me say that that passing model code to your views is never a good idea. But if you insist :
<%= render :partial => 'some_partial',
:locals => {:some_variable => "somevalue",
:some_other_variable => some_other_variable} %>

Accessing nested model attributes inside a fields_for without using FormBuilder

I have a Rails form that is being used for creating and editing a model with a has_many relationship. I'm very familiar with typical forms with nested models, but my current problem requires accessing rendering some form elements using typical FormBuilder helpers and other HTML elements using data from the model itself. For example, my top level form has something like:
<% customer_form.fields_for :customer_images do |images_form| %>
<%= render :partial => 'customer_image_show', :locals => { :f => images_form } %>
<% end %>
Then, in the form partial, I need to do something like:
<dd><%= f.text_field :image_description %></dd>
... but also access attributes from the customer_images model (for example, the ID of the customer_image record).
I feel like this should be pretty straightforward and I'm just missing something basic. Any help is appreciated. This is a Rails 2.3.8 application.
You can call
f.object
to get to the object that the form is associated with.
Not sure if this is what you need, but couldn't you include the model data as a local? like:
<%= render :partial => 'customer_image_show', :locals => { :f => images_form, :customer_image => #customer_image } %>

Resources