Rendering partial for nested object not processing object nor locals - ruby-on-rails

An enumeration of objects, has nested objects. The goal is to render a partial for futher nested objects
<% groups.each do |group| %>
<% group.children.each do |child| %>
<% if child.lessons.size > 0 %>
<% render 'child_partial' %>
<% end %>
<% end %>
<% end %>
When the partial is defined as as per the Rails guides
<% render 'child_partial', locals: {child: child} %>
or
<% render 'child_partial', object: child %>
error undefined local variable or method 'child' for #<ActionView::Base is returned when the partial calls (for testing purposes) <%= child.class %>
How can I pass the object to the partial so that it may be processed properly?

You just need to follow the guides literally:
<%= render partial: 'child_partial', locals: {child: child} %> # or
<%= render 'child_partial', child: child %>
And it's better to render with collections for performance:
<% groups.each do |group| %>
<%= render partial: 'child_partial',
collections: group.children.select { |child| child.lessons.size > 0 },
as: :child %>
<% end %>

render will not accept additional local variables for the partial, you need to use render partial: as following for that:
<% render partial: 'child_partial', locals: {child: child} %>

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.

how to render multiple js.erb files in same method in rails?

def react
#postsAlPHA = #user.find(params[:liked_post]).page(params[:page])
#postsBETA = #user.find(params[:disliked_post]).page(params[:page])
end
so I am trying to make #postsAlPHA to render alpha.js.erb for pagination
and #postsBETA to render
BETA.js.erb
<% #postsAlPHA.each do |x| %>
<% x.body %>
<% end %>
<%= paginate #postsAlPHA %>
<% #postsBETA.each do |u| %>
<% x.content %>
<% end %>
<%= paginate #postsBETA %>
Turn them into partials, then render them in your view. Make sure to prefix the filenames with _ e.g. _alpha.js.erb.
In your view:
<%= render partial: 'path/to/alpha.js.erb' %>
<%= render partial: 'path/to/beta.js.erb' %>

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.

Rails: How to use same partial file for one to many relationship?

For the normal situation. Different views can use the same partial like this
<h1>New zone</h1>
<%= render partial: "form", locals: {zones: #zones} %>
<h1>Editing zone</h1>
<%= render partial: "form", locals: {zones: #zones} %>
<% zones.each do |zone| %>
<%= zone.location%>
<% end %>
But my situation is a bit different, the origin code like this
one belongs_to two #one = One.all
one.html.erb
<%= render partial: "one",locals:{one: #one} %>
_one.html.erb
<% one.each do |n|%>
<%= n.location%>
<% end %>
two has_many one #two = Two.all
two.html.erb
<%= render partial: "two", #two %>
_two.html.erb
<% #two.each do |one|%>
<% one.each do |n|%>
<%= n.location %>
<% end %>
<% end %>
For this situation, how can I code render for two.html.erb if I want one.html.erb and two.html.erb use the same partial _one.html.erb ?
this one is definitely incorrect, but how to correct this?
two.html.erb
<%= render partial: "one/one", locals: {one: #two} %>
========================update============================
I think the basic of question is whether we can use the same partial for an object and at the same time for a collection.

How to iterate through an array from a specific point to the end of array in Rails

I need to iterate through an array starting at a specific point in the array to the very end of it.
For example:
<% #posts[6.."To the very end of array"].each do |post| %>
<%= render partial: 'posts/post', locals: {post: post} %>
<% end %>
Here is a more complete example of what I'm trying to accomplish.
<% #posts.each do |post| %>
<% if post == #posts.first && !params[:page] %>
<div class="hidden-phone hidden-tablet">
<%= render partial: 'posts/main_post', locals: {post: post} %>
</div>
<div class="visible-phone visible-tablet">
<%= render partial: 'posts/post', locals: {post: post} %>
</div>
<%= render partial: 'posts/add_post' %>
<% end %>
<% end %>
<% #posts[1..5].each do |post| %>
<%= render partial: 'posts/post', locals: {post: post} %>
<% end %>
<%= render partial: 'posts/add2_post' %>
<% #posts[6..11].each do |post| %>
<%= render partial: 'posts/post', locals: {post: post} %>
<% end %>
<%= render partial: 'posts/add3_post' %>
<% #posts[12.."To the very end of array"]each do |post| %>
<%= render partial: 'posts/post', locals: {post: post} %>
<% end %>
Is there a more efficient way to accomplish this?
Thanks for your help.
You can use the length of the array, like so:
<% #posts[6..#posts.length].each do |post| %>
<%= render partial: 'posts/post', locals: {post: post} %>
<% end %>
Technically you should be doing length-1 but that can be tedious to type, and if you supply a number larger than the bounds of the array, Ruby will just not go past it anyways.

Resources