Reputation: 139
Rails beginner project In a view that I want to show all results from two different models (MediaLink & MediaCollection) I have successfully created a two dimensional array @ranked_media that holds
[0] is id from table
[2] is total_points
[5] is class name as a string.
Being that they are pulled from 2 different tables, the id can be repeated twice, but won't have the same class name if id are identical.
In my view (pages/media.html.erb) :
<div class="container">
<% @ranked_media.each do |media| %>
<% if media[5] == 'MediaCollection' %>
<%= render 'media_collection_show' %>
<% else %>
<%= render 'media_link_show' %>
<% end %>
<% end %>
</div>
partial _media_collection_show.html.erb :
<h2 class="text-center mt-4 text-white">
is a MEDIA COLLECTION of class :: <%= @media_collections.class %>
</h2>
partial _media_link_show.html.erb :
<h2 class="text-center mt-4 text-white">
is a MEDIA LINK of class :: <%= @media_links.class %>
</h2>
At this point all is fine. The block is being generated 5 times and applies the output according to the each block. The partials also outputs the class name to make sure they all work.
My Problem
However, I can add this to the view (3rd line is the change) :
<div class="container">
<% @ranked_media.each do |media| %>
<%= media %>
<% if media[5] == 'MediaCollection' %>
<%= render 'media_collection_show' %>
<% else %>
<%= render 'media_link_show' %>
<% end %>
<% end %>
</div>
And it outputs media object. But if try that in any of the partials like this :
<h2 class="text-center mt-4 text-white">
is a MEDIA LINK of class :: <%= @media_links.class %>
<%= media %>
</h2>
I get NameError in Pages#media undefined local variable or method `media'
How can I access the media block element inside these two partials?
Upvotes: 0
Views: 52
Reputation: 770
By sending in local variables to the partials: <%= render 'media_link_show', media: media %>
. In the partial you'd access it like so:
<h2 class="text-center mt-4 text-white">
is a MEDIA Object of class :: <%= media.class %>
</h2>
Note the lack of @
; in general it's bad form to access instance
variables in partials.
Your third line (<%= media %>
) also does nothing for the functionality, and can safely be removed.
Edit: When a controller does @items = ...
in an action, it sets @items
as an instance variable; any view rendered from that action has access to that value, which is why your @ranked_media
can be looped over.
Partials are meant to be re-used, and not necessarily by the same view/controller, so if a partial accesses an instance variable, like your _media_collection_show.html.erb
does, then any view/controller that uses that partial will need to set the @media_collections
variable.
To avoid this (a controller action should strive to only set one instance variable), you can instead inject local variables into a partial: <%= render "partial_name", items: @items %>
. Here, we're setting the local variable items
to be the value of @items
. By doing this, any view that uses the partial can send in their own items into the partial, without the need for the controller to set a "magical variable" @items
. You could, for example, do: <%= render "partial_name", items: [1, 2, 3] %>
. You've decoupled the partial from the controller.
Upvotes: 1