bryant
bryant

Reputation: 25

Incorrect partial being rendered in my rails app

I've been stumped as to why my rails app is rendering the wrong partial. I have two partials, each related to a different controller (invitations and guests controllers). One partial lists the number of invitations sent out to users and the second partial lists those users who have confirmed their invitation. In addition, the second partial also allows one to see a simple profile of the confirmed guests.

What is happening is that when I visit the link related to the guests controller events/1/guests/, I expect to see the partial related to the guest profile. Instead, the partial related to the invitations controller is rendered. Both the invitations and guests controllers are nested resources of events.

Below is the code that I have been working with. Thanks!

Routes

resources :events, only: [:new, :show, :create] do
    resources :invitations, only: [:new, :create, :show]
    resources :guests, only: :show
end

match '/events/:id/guests', to: 'guests#show'

Guests controller

def show
   @event = Event.find_by_id(params[:id])
   @guestlist = @event.invitations.where(accepted: true)
end

views/guests/show.html.erb

<% provide(:title, @event.eventname + " Guest List") %>
<h1> Guest list for <%= @event.eventname %> </h1>

<% if @event.invitations.any? %>
   <%= render @guestlist %>
<% end %>

views/guests/_guestlist.html.erb

<li>
<%= guestlist.name %> | <%= guestlist.occupation %> | 
    <%= guestlist.interests %>  
</li>

Instead, the following partial is being rendered:

views/invitations/_invitation.html.erb

<li>
<%= invitation.name %> | <%= invitation.email %> | 
<% if invitation.accepted == true %> <%= "Confirmed" %> <% else %> <%= "Pending" %> <% end %>
</li>

Upvotes: 1

Views: 227

Answers (3)

zeantsoi
zeantsoi

Reputation: 26203

The following snippet depicts the correct way to invoke your partial:

# app/views/guests/show.html.erb
<%= render :partial => 'guests/guestlist', :locals => {:guestlist => @guestlist} %>

Since you need access to the @guestlist instance variable in your partial, you'll need to pass it as a local. Then, in your partial, guestlist will be available as a local variable.

Then, within your partial, you'll need to iterate over the members of your guestlist:

# app/views/guests/_guestlist.html.erb
<% guestlist.each do |guest| %>
    <li> 
         <%= guest.name %> | <%= guest.occupation %> | <%= guest.interests %>  
    </li>
<% end %>

UPDATE:

The reason the OP's original invocation of the partial rendered the invitation partial is that @guestlist is actually comprised of Invitation objects, and thus, the <%= render @guestlist %> method was actually looking for a partial named invitation. From the canonical Rails guides:

There is also a shorthand for this. Assuming @products is a collection of product instances, you can simply write this in the index.html.erb to produce the same result:

<h1>Products</h1> 
<%= render @products %>

Rails determines the name of the partial to use by looking at the model name in the collection.

Because of this, you need to explicitly declare the name of the partial you want to use, otherwise ActionView will use the invitation partial by default.

Upvotes: 2

Nerve
Nerve

Reputation: 6891

If @guestlist is an object of type Guest, then it would by default render _guest.html.erb.

So, you can try This

<%= render 'guestlist' %>

Variable @guestlist would be automatically available in the partial, so no need to pass it in locals.

Hope this works.

Upvotes: 1

Bachan Smruty
Bachan Smruty

Reputation: 5734

In your show action, you have defined

@guestlist = @event.invitations.where(accepted: true) # it returns array of obejects or records

Now, Please have a try with the following code

views/guests/show.html.erb

<% unless @guestlist.blank? %>
   <%= render "/guests/guestlist" %>
<% end %>

views/guests/_guestlist.html.erb

<% @guestlist.each do |guestlist| %>
 <li>
  <%= guestlist.name %> | <%= guestlist.occupation %> | 
    <%= guestlist.interests %>  
 </li>
<% end %>

Upvotes: 0

Related Questions