Reusing a partial in the same page - ruby-on-rails

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.

Related

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

How to call a form from an element

I have Post with nested elements who also have different nested form (text for this example) according to a :cat variable.
To create the texts I'm using a post method create_element with a variable (cat = 1). And I would like to call an AJAX method to render the new text created into my post form.
My problem: I don't know how to call the text nested_form created directly into my AJAX method.
My code :
Post form (posts/new):
<%= simple_form_for #post do |f| %>
<div class="elements">
<%= f.fields_for :elements do |element| %>
<%= render 'posts/element_field', f: element %>
<% end %>
</div>
<div class="btn_add_element_area">
<a href="/posts/<%=#post.id%>/create_element?cat=1" data-method="patch" data-remote="true">
<i class="fa fa-font"></i>
</a>
</div>
<%= f.submit "Publish", class: "btn" %>
<% end %>
Post form (posts/_element_field):
<div class="element_form" id="element_form<%= f.object.id %>">
<div class="undisplay">
<%= f.number_field :cat %>
</div>
<%- if f.object.cat == 1 %>
<%= f.fields_for :post_texts do |text| %>
<%= render 'posts/elements/text_field', f: text %>
<% end %>
<% end %>
</div>
Post form (posts/_text_field):
<%= f.text_area :content %>
Post controller (create_element) :
def create_element
if params[:cat] == "1"
#element = Element.create(post: #post, cat: 1)
Text.create(element: #element)
end
respond_to do |format|
format.js {render 'elements/create'}
end
end
And the AJAX method (elements/create) :
$('.elements').append("<%= j render partial: 'posts/element_field', locals: {f: #element} %>");
Error = undefined method `object'
The problem is that in the AJAX file I call the #element created for my f variable instead of calling the form of this #element.
I also tried something like that for the AJAX method, but still not working :
<% form_for(#element) do |elm| %>
$('.elements').append("<%= j render partial: 'posts/element_field', locals: {f: elm} %>");
<% end %>
Error = undefined method `element_path'
Or
<%= simple_form_for(#post) do |p| %>
<%= p.fields_for :elements, #element do |elm| %>
$('.elements').append("<%= j render partial: 'posts/element_field', locals: {f: elm} %>");
<% end %>
<% end %>
No error but nothing happen
If you have any ideas to solve that, I would really appreciate !
PS: And ideas to improve the question title are welcome !!

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.

Passing multiple variables to partial

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

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