Passing multiple variables to partial - ruby-on-rails

I get error in partial line #1: undefined local variable or method 'level'
Code in my view:
<div id="comments">
<% level = 0%>
<% #comments.each do |comment| %>
<%=render partial: 'comments/single_comment', locals: {level: level, comment: comment} %>
<% end %>
<% if 0 < level %>
<% (level).times do %>
</div>
<% end %>
<% end %>
</div>
</div>
And partial first lines:
<% if comment.level < level %>
<% (level - comment.level).times do %>
</div>
<% end %>
<% end %>
Any idea what's wrong here?

Looks like this code should be work(it's no so good, but it should be work)
I think problem that you use your partial (comments/single_comment) elsewhere in some part of code what we didn't see without 'level local' :)

seems like the code is right .. try to check if you have any partial view that use single_comment filename ... and also you can use collection instead doing a loop
<%= render partial: 'comments/single_comment', collections: #comments, locals: { level: level } %>

You are passing arguments to the partial in a wrong way. update it to following.
<%=render partial: 'comments/single_comment', locals: => {:level => level, :comment => comment} %>
now you can access your objects in partials as follows
<% if locals[:level] < level %>
<% (level - locals[:level]).times do %>
</div>
<% end %>
<% end %>

Related

Reusing a partial in the same page

I have a controller with 3 objects and i want to call the same partial three time with each object
class HomeController < ApplicationController
def index
#evaluations_teams = Evaluation.eager_load(:user).where(users: {status: true}).where(team_id: current_user.student_details.last.team_id).all.order(created_at: :desc).limit 5
#evaluations_stage = Evaluation.eager_load(:user).where(users: {status: true}).where(stage_id: current_user.student_details.last.stage_id).all.order(created_at: :desc).limit 5
#evaluations_schools = Evaluation.eager_load(:user).where(users: {status: true}).where(school_id: current_user.student_details.last.school_id).all.order(created_at: :desc).limit 5
end
end
INDEX.HTML.ERB
<%= render 'home/partials/loop_areas', locals: {evaluations:#evaluations_teams} %>
<%= render 'home/partials/loop_areas', locals: {evaluations:#evaluations_stage} %>
<%= render 'home/partials/loop_areas', locals: {evaluations:#evaluations_schools} %>
Partial: home/partials/_loop_areas.html.erb
<% #evaluations.each do |evaluation| %>
<div class="div-card-infosaluno">
<div class="card-aluno"><%= evaluation.user.full_name %></div>
<div class="card-serie"><%= "#{evaluation.stage.name} · #{evaluation.school.name}" %></div>
</div>
<% end %>
This returns:
undefined method `each' for nil:NilClass
on <% #evaluations.each do |evaluation| %>
How can i do this?
You're trying to access an instance variable #evaluations in your partial but it is not defined in the controller action.
You've to instead loop through the local variable evaluations.
<%# home/partials/_loop_areas.html.erb %>
<% evaluations.each do |evaluation| %>
...
<% end %>
And your view should be
<%= render 'home/partials/loop_areas', evaluations: #evaluations_teams %>
<%= render 'home/partials/loop_areas', evaluations: #evaluations_stage %>
<%= render 'home/partials/loop_areas', evaluations: #evaluations_schools %>
You can also pass a hash to the render method but I feel it is more verbose.
<%= render partial: 'home/partials/loop_areas', locals: { evaluations: #evaluations_schools } %>
Please try the below code in Partial: home/partials/_loop_areas.html.erb
It should work as you are expecting.
<% evaluations = local_assigns[:evaluations] %>
<% evaluations.each do |evaluation| %>
<div class="div-card-infosaluno">
<div class="card-aluno"><%= evaluation.user.full_name %></div>
<div class="card-serie"><%= "#{evaluation.stage.name} · #{evaluation.school.name}" %></div>
</div>
<% end %>
Thanks.

Trying to make my partial work

I need to iterate through two sets of values on the same web page so I wrote a partial to eliminate duplicate code. The two variables that I am trying to iterate through are #bookmarks and #liked_bookmarks.
The partial is rendered properly if I use either #bookmarks or #liked_bookmarks in the partial it's self but then the only one of the value sets are displayed. in the code below I tried using #resource as a stand in that will have #bookmarks and #liked_bookmarks passed into it.
this is the partial that is located in app/views/bookmarks/_bookmarksandlikes.html.erb
<div>
<% #resource.each do |x| %>
<%= x.url%>
<% end %>
<div>
and this is the code for the page that I am calling the above partial on located in app/views/users/show.html.erb
<h1>My Blocmarks</h1>
<p>Find me in app/views/users/show.html.erb</p>
<div>
<h1>Blockmarks I have created </h1>
<div class =row>
<%= render partial: 'bookmarks/bookmarksandlikes', locals: { topic: #bookmarks} %>
</div>
</div>
<div>
<h1>Blockmarks I have liked
<%= render partial: 'bookmarks/bookmarksandlikes', locals: { topic: #liked_bookmarks} %>
</h1>
</div>
You're close. Instead of #resource just use topic, which you are passing in as a local.
<div>
<% topic.each do |x| %>
<%= x.url%>
<% end %>
<div>
Since you are not passing #resource into partial and passing only topic variable you need to do it
<div>
<% topic.each do |x| %>
<%= x.url%>
<% end %>
<div>
Instead of:
<div>
<% #resource.each do |x| %>
<%= x.url%>
<% end %>
<div>
Do it:
<div>
<% topic.each do |x| %>
<%= x.url%>
<% end %>
<div>
Because you pass the object on locals: { topic: #liked_bookmarks} you should use topic instead of using any instance that is not initialize.

Rails loop in html erb

How can I simplify the following lines:
<% if #campaign.previous_campaign.present? %>
<%= #campaign.previous_campaign.product_name %>
<% if #campaign.previous_campaign.previous_campaign.present? %>
<%= #campaign.previous_campaign.previous_campaign.product_name %>
<% end %>
<% end %>
I need to keep adding ".previous_campaign" until it is not present. So the next one in the above code would be:
<%= #campaign.previous_campaign.previous_campaign.previous_campaign.product_name %>
etc etc.
Something like this:
<% campaign = #campaign %>
<% while campaign.previous_campaign.present? %>
<% campaign = campaign.previous_campaign %>
<%= campaign.product_name %>
<% end %>
The code may need some debugging, but I guess the idea is clear
You could do something like this:
<% for c in #campaign do %>
<% if c.previous_campaign.present? %>
<%= c.previous_campaign.product_name %>
<% end %>
<% end %>

Group posts by Year - Rails

I have model called "Shoes" that belongs to the a model called "History". I want to show all of the shoes in my History show.html.erb page, but I want to group them by their release date. (I have an attribute called release for that).
I'm using this example from Railscasts:
shoes_controller
def index
#shoes = Shoe.all(:order => 'release, name')
#release_year = #shoes.group_by { |t| t.release.beginning_of_year }
end
Shoes index.html.erb view
<% #release_year.each do |release, shoes| %>
<% shoes.each do |shoe| %>
<%= shoe.name %>
<% end %>
<% end %>
I want to be able to do this but on my History show.html page, how can i accomplish this?
What I have so far:
History show.html.erb
<% #history.shoes.each do |shoe| %>
<div class="shoe">
<%= shoe.name %>
</div>
<% end %>
Thanks.
Perhaps you may want to create a _shoes_by_year partial in the shoe views, and then render the shoe collection:
views/shoes/_shoe.html.erb
<div class=shoe>
<%= shoe.name %>
</div>
views/shoes/_shoes_by_year.html.erb
<% shoes_by_year.each do |release_year, shoes| %>
<div>
<h3><%= release_year.year %></h3>
<%= render 'shoes/shoe', collection: shoes %>
</div>
<% end %>
histories_controller.rb
def show
...
#shoes = #history.shoes.group_by { |shoe| shoe.release.at_beginning_of_year }
end
/views/history/show.html.erb
...
<%= render 'shoes/shoes_by_year', object => #shoes %>

How can I pass more than 2 arguments to partial?

I want to pass 2 arguments such as topic and icon_photo.
How can I do that?
undefined method `icon_photo?'
I got this error with the code below.
view
<div class="Topic">
<% #community.topics.each do |topic| %>
<%= render 'topics/topic', :topic => topic, :icon_photo => topic.user.profile.avatar %>
<% end %>
</div>
You can pass a locals hash:
<div class="Topic">
<% #community.topics.each do |topic| %>
<%= render 'topics/topic', locals: {topic: topic, icon_photo: topic.user.profile.avatar, etc: 'blabla' } %>
<% end %>
</div>
See some documentation here:
http://www.tutorialspoint.com/ruby-on-rails/rails-render.htm
A little improvement can be mabe, you can render your collection like this:
<div class="Topic">
<%= render partial: 'topics/topic', collection: #community.topics %>
</div>
# in your partial topics/_topic.html.erb:
<% icon_photo = topic.user.profile.avatar %>

Resources