Pass a variable into a partial, rails 3? - ruby-on-rails

I have a loop like such:
<% #posts.each do |post| %>
<% render middle %>
<% end %>
Then in my middle partial, how do I access the current post?

Try this:
<% #posts.each do |post| %>
<%= render 'middle', :post => post %>
<% end %>
Like this you'll have a local variable post available within the partial.

Give it to the partial as a local variable
<%= render :partial => 'middle', :locals => { :post => post } %>
Of course, rails also has a shortcut for rendering collections:
<%= render :partial => 'post', :collection => #posts %>
In this case it will call the partial post for every post with a local variable 'post'
You can even render a spacer template between each post:
<%= render :partial => 'post', :collection => #posts, :spacer_template => 'post_divider' %>

<% #posts.each do |post| %>
<% render middle, :post => post %>
<% end %>
You can now access post as the local variable post in the partial

Replace <%= render middle %> with <%= render middle, :post => post %>. Then in your middle partial, you can access the post variable.

You can replace the entire each block with this:
<%= render partial: "product", collection: #posts %>
Or even shorter:
<%= render #posts %>
Full documentation (section 3.2)
https://guides.rubyonrails.org/action_view_overview.html

Related

Render a collection of forms using partial

Rails has this pretty way to render a collection using partial
<%= render partial: 'erb_partials/post', collection: #users, as: :user %>
How can I apply this in my loop of forms?
<%= profile_form.fields_for :item_groups, #item_groups do |item_form| %>
<%=render partial: 'item_groups/item_group', locals: {item_form: item_form}%>
<% end %>
<%=profile_form.submit%>
In your case you can't use the render partial: 'path', collection: #list method.
If you unfold your first example:
<%= render partial: 'erb_partials/post', collection: #users, as: :user %>
You get:
<% #users.each do |user| %>
<%= render 'erb_partials/post', user: user %>
<% end %>
The above is such a common action that the render method included the :partial option to wrap the render call in an each loop. render doesn't include any other iteration wrapper options at this moment.

passing variable to simple form symbol

this is my _form_item partial in which I used symbol :order_item
<%= simple_form_for :order_item do |f| %>
.....
<% end %>
here is my view in which I want to render that partial:
<%= content_tag_for :tr , #order.order_items do |i| %>
<div class="hide">
<%= render :partial => "form_item" %>
</div>
<% end %>
How can I pass "i" object to :order_item?
UPDATE:
I prefer to keep it ":order_item" instead of changing it to something like "foo".
You should have:
<%= render partial: 'form_item', locals: {order_item: i} %>
or a shorthand:
<%= render 'form_item', order_item: i %>
And in your form_item partial you should have:
<%= simple_form_for order_item do |f| %>
...
Just do
<%= simple_form_for item do |f| %>
.
.
<% end %>
and render the partial via
<%= render :partial => 'form_item', :locals => { :item => i } %>
You can pass i as a locals to the partial like follows:
<%= render :partial => "form_item", :i => i %>
and you'll have i available in the _form_item partial.
Update:
Local variables passed to partials are variables and not symbols. You could keep the name order_item like follows:
<%= render :partial => "form_item", :order_item => i %>
And update your order_item partial as follows:
<%= simple_form_for order_item do |f| %>
.....
<% end %>
I think I understand why you do not want to change :order_item to just order_item. I think you are going to have to update your other calls to pass in local variable order_item where ever you are making a call to this partial.

Refactoring into partials in Rails

In page1, I use code A+B+C
In page2, I use code B+C
So when I make a partial, I realy have no idea in how to deal with this.
For example, In a Post-Comment system. I want to show #comments in 2 different pages. In the comment index page,
We show the post it belongs to. And in the post show page, We only have to show the comments content.(Since there is no need to show the comment.post again)
#Comment Index Page
<% #comments.each do |comment| %>
<%= comment.post %>
<%= comment.author %>
<%= comment.content %>
<% end %>
..
#Post Show Page
<% #comments.each do |comment| %>
<%= comment.author %>
<%= comment.content %>
<% end %>
So, how do I make a partial to reuse the code? Perhaps like this? But this there more elegant way of doing this?
#Comment Index Page
<% #comments.each do |comment| %>
<%= comment.post %>
<%= render comment %>
<% end %>
#Post Show Page
<% #comments.each do |comment| %>
<%= render comment %>
<% end %>
Updated:
I adopt the local variable approach, and update my code like:
# partial
<% if include_topic %>
<div class="Topic">
<h5><%= link_to "#{comment.topic.content}", comment.topic %></h5>
</div>
<% end %>
#Index
<%= render #comments, :locals => {:include_topic => true } %>
But I get undefined local variable or method `include_topic' for #<#
I just find nowhere to debug this issue
Your partial:
<%= comment.post if include_post %>
<%= comment.author %>
<%= comment.content %>
your code:
#index page
<%= render :partial => "partial_path", :collection => #comments, :as => :comment, :locals => {:include_post => true } %>
#show page
<%= render :partial => "partial_path", :collection => #comments, :as => :comment, :locals => {:include_post => false } %>
Syntax could be much shorter but it depends whether or not you stick to rails conventions see doc.
Sidenote: I don't like 1.8.7 syntax
In the partial,
<% comments.each do |comment| %>
<%= comment.post if params[:controller] == "comments" %>
<%= comment.author %>
<%= comment.content %>
<% end %>
and now render this partial in both comments/index and posts/show pages by specifying the comments as a local variable.

adding an if statement within brakets in ruby on rails

I have the following in my view .html.erb:
<%= form_tag :action=>"edit", :id => #product.id do %>
I want to basically only add the id if #product exists (not null i suppose) so i want to do something along the lines of:
<%= form_tag :action=>"edit" if #product print",:id => #product.id" end do %>
I know the above is wrong code but that's the idea behind it, not sure if i can embed that within the <%= tag.
Thanks
try
<%= form_tag :action=>"edit", :id => (#product.id if #product) do %>
<%
url_options = { :action => "edit" }
html_options = {}
html_options[:id] = #product.id if #product
%>
<%= form_tag url_options, html_options do %>
<% .... %>
<% end %>
http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-form_tag
http://apidock.com/rails/v3.2.8/ActionView/Helpers/FormTagHelper/form_tag
This should work:
<% if #product %>
<%= form_tag :action=>"edit",:id => #product.id" do %>
<% else %>
<%= form_tag :action=>"edit" do %>
<% end %>
You can probably embed the conditional code in the <%= ... %> tag if you use eval but the above might be more clear!

Why my partial won't receive parameters correctly?

When rendering a partial called 'member', it says error
undefined local variable or method `user' for #<#:0x000000095ec8c0>
Why??
My codes are
View
<% #users.each do |user| %>
<%= render 'member', :locals => {:user => user} %>
<% end %>
Partial
<div class="chapter">
<p class="title">
<%= user.user_profile.nickname %>(<%= user.username %>)
</p>
You should use:
<%= render :partial => 'member', :locals => { :user => user } %>
Or just with:
<%= render 'member', :user => user %>
My advice is that you stick to the conventions whenever you can; everything will go a lot smoother for you if you do.
If you had a _user.html.erb partial, you could be using this rails convention
<% #users.each do |user| %>
<%= render user %>
<% end %>
But you can even shorten this more
<%= render #users %>
Huzzah!
I strongly suggest you check out the Layouts and Rendering Guide

Resources