Rendering a partial using specific controller variables - ruby-on-rails

I am trying to play with Rails naming conventions as in here and render two different pages with different variables using one partial.
index
<%= render #events_future %>
current
<%= render #events_current %>
event controller
def index
#events_future = ...
end
_event.html.erb
<% #events.each do |event| %>
...
<% end %>
I get the undefined "each" method
Please point me in the right direction

I think the best thing to do here is to pass a locals to the partial _event.html.erb because the partial needs to display different objects like follows:
index
<%= render 'event', events: #events_future %>
current
<%= render 'event', events: #events_current %>
In the above two render statements, the events gets passed to the event partial as a local.
Then in your _event.html.erb you would do:
<% events.each do |event| %>
...
<% end %>

Do you have #events initialized in your controller?
I see that you have #events_future and #events_current, but if #events is not defined in the controller, your view wouldn't know what you are referring to.
If you want to reuse events for both future and current, use the following in each view
<!-- index.html.erb -->
<%= render 'event', events: #events_future %>
<!-- current.html.erb -->
<%= render 'event', events: #events_current %>
This renders the _event.html.erb partial and sets the events local variable. In _event.html.erb, use
<% events.each do |event| %>
<!-- do stuff -->
<% end %>

You have to pass the variable to the partial when you render it:
render :partial => 'event', :locals => {:events => #events_current} %>
render :partial => 'event', :locals => {:events => #events_future} %>
And then in your partial you do:
<% events.each do |event| %>
...
<% end %>

Related

Rendering collections within collection in Rails

This is driving me crazy, I thought it should be something very simple but I've spent all day trying to figure it out and getting nowhere. I've looked all over, there's something I must be missing.
I want to render a partial for a collection, within a partial from a collection.
Eg. I have a collection of entries which I want to render in my feed partial, I want feed to come from a collection of feeds, such that the page displays all entries in all feeds.
How can I do this?
Something like:
controller:
#feeds = Feeds.all
allmyfeeds.html.erb
#feeds.each do |feed|
<%= render 'feed' %>
<% end %>
or
<%= render 'feeds', collection: #feeds %>
_feed.html.erb
<%= render 'items', collection: #items %>
_item.html.erb
<%= item.summary.html_safe %>
But I really don't know.
Partial naming conventions will really help you out here...
In allmyfeeds.html.erb (which i'm guessing is actually feeds/index.html.erb), instead of this...
#feeds.each do |feed|
<%= render 'feed' %>
<% end %>
You can simply call this...
<%= render #feeds %> # this will invoke _feed.html.erb for every feed in the collection, automatically
Inside your _feed.html.erb partial...
# Note: You may need to change `items` to something like `items/items` if it is not located in the same directory
<%= render partial: 'items', locals: { items: feed.items } %>
Then in your items partial, you will have access to items, which is a collection of items for that particular feed
Somehting like:
<% #feeds.each do |feed| %>
<%= render partial: 'feed', locals: { feed: feed } %>
<% end %>
In your _feed.html.erb:
<h1><%= feed.id %> </h1>
<% feed.entries.each do |entry| %>
<&= render partial: 'entry', locals: { entry: entry } %>
<% end %>
In your _entry.html.erb:
<h2><%= entry.id %></h2>
I'm assuming your Feed model has a has_many :entries association, if it's not the case (and what you want is to render the same collection of #entries in each feed), then you just need to pass the #entries collection to the _feed.html.slim partial, like:
render partial: 'feed`, locals: { feed: feed, entries: #entries }
and update your _feed.html.erb

Rails partial looping through local_assigns

I'm populating a partial with many instance variables in the locals hash. Is there a way to pull multiple instance variables from local_assigns in the partial?
<%= render 'tabs', :locals => {:tab1 => #news, :tab2 => #people, :tab3 => #tags} %>
In the partial I'd like to create a dynamic set of tabs based on the number of instance variables I populate the locals with.
<% local_assigns.each do |local_assign| %>
<% local_assign.each do |tabs| %>
<!-- Grab tab class name -->
<li class="tab"><%= tabs[:class] %></li>
<% end %>
<% end %>
Why don't you just pass it as an array
render 'tabs', :locals => {:tabs => [#news, #people, #tags]} %>
in your view
<% tabs.each do |tab| %>
<!-- Grab tab class name -->
<li class="tab"><%= tab[:class] %></li>
<% end %>
Thanks Vimsha I ended up using collection instead of locals and created the instance variable in the controller.
http://guides.rubyonrails.org/layouts_and_rendering.html
Controller
#tabs = [#news, #people]
View
<%= render 'tabs', :collection => #tabs %>

Passing in variable to rails partial

Right now I have a rails partial that looks like this:
<%= render :partial => "/talk/partials/comment", :collection => #comments, :locals => {:votes => #votes} %>
I am passing in a collection of comments and another local variable.
That comment partial then goes right into using the comment variable and works fine.
I have since made another partial called '/talk/partials/comment_2014'. When I try this, I am getting the error undefined local variable or method 'comment'. From what I can gather, when I have a different partial name, something with the variable also changes. I would like to keep the same comment variable for the new partial ''/talk/partials/comment_2014'. How would I go about doing this?
Something I tried which did not work was the following:
<% #comments.each do |comment| %>
<%= render :partial => "/talk/partials/comment_2014", comment: comment, :locals => {:votes => #votes} %>
<% end %>
which did not work either.
You can do it this way
<% #comments.each do |comment| %>
<%= render "/talk/partials/comment_2014", comment: comment, votes: #votes %>
<% end %>
Or
<% #comments.each do |comment| %>
<%= render partial: "/talk/partials/comment_2014", locals: { comment: comment, votes: #votes } %>
<% end %>
Notice in the second way the comment is inside the locals.

ruby on rails render deosn't find the file

I'm new to ruby on rails.
In views/events I have "_form.html.erb" which is rendered in "new.html.erb" by this code:
<%= render "form" %>
Now I want to render "_form.html.erb" in "index.html.erb" which is in the same folder(views/events).
But I get the error "missing template".
I guess I have to add some thing to controller, please help me to render form in other pages of views...
You "usually" don't render a form in an index action. Most form partials are setup semantically to expect a #my_resource, but if you're doing everything the rails way you're not going to have a instance variable during your index action. There's a number of ways you can do this but this is probably the quickest.
You probably have some collection (let's pretend you're using books) in your index action:
#views/books/index.html.erb
<% #books.each do |book| %>
...
<%= render "form" %>
...
<% end %>
You can just set an instance variable somewhere prior to rendering the form:
#views/books/index.html.erb
<% #books.each do |book| %>
<% #book = book %>
...
<%= render "form" %>
...
<% end %>
Another way to do it would be through passing in some locals to a partial. You'd have to change all of your references in _form to use a local variable instead. Then you can call render like this:
<%= render :partial => "form", :locals => {:book => book } %>
You can try
<%= render "events/form" %>
I had this problem before and this solved

Rendering content inside a partial via =yield

I'm creating an application with ruby on rails where I have an items/_item.html.erb. Inside the partial is a yield statement so i can add extra content as needed. In this case, I want to add a specific button to item depending on what view calls partial.
This is what I've tried and it renders the partial, but it does not render the block:
_item.html.erb
<%= yield if block_given? %>
<div>
<%= item.name %>
</div>
someview.html.erb
...
<% render(:partial => 'items/item', :collection => current_user.items do %>
<%= "HELLO" %>
<% end %>
...
I have also tried using content_for and some other stuff with no success. Is there a way to be able to render specific content inside a partial via yield? I'm currently using Rails3
EDIT:
I've found out that it's the :collection hash that makes it impossible insert the block.
Both of this pieces of code work:
<%= render :layout => 'items/item' do %>
Hello world
<% end %>
<%= render :layout => 'items/item', :locals => {:item => current_user.items.first} do %>
Hello world
<% end %>
This means that if i do a .each i could accomplish what I want but it would be ugly code. Anyone know a way around this?
content_for should work fine in this case. Here is the code I just double checked locally.
somewhere.html.erb
<% content_for :foobar do %>
fubar
<% end %>
_item.html.erb
<% if content_for? :foobar %>
<%= yield :foobar %>
<% end %>

Resources