Reputation: 194
I'm trying to display all of the comments on all of a user's posts in a has_many_through association.
routes.rb:
resources :posts do
resources :comments
end
models:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :comments, :through => :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
users_controller.rb
def activity
@user = current_user
@posts = @user.posts
@comments = @user.comments
end
activity.html.erb
<h4>My Activity</h4>
<ol class="posts">
<%= render @comments.last(3) %>
</ol>
_comment.html.erb
<div class="comment" id="comment-<%= post.id %>-<%= comment.id %>">
<%= link_to smavatar_for(comment.user), user_path(comment.user.name) %>
<span class="user"><%= link_to comment.user.name, user_path(comment.user.name) %></span>
<div class="comment-content">
<%= simple_format(comment.content) %>
</div>
</div>
The line <%= render @comments.last(3) %>
in activity.html.erb gives the error
undefined local variable or method `post' for Class
for the line <div class="comment" id="comment-<%= post.id %>-<%= comment.id %>">
in _comment.html.erb. I know I probably need to pass local variables to the partial, I just can't figure out how to do it. <%= @comments.last(3) %>
instead of <%= render @comments.last(3) %>
prints all the comment params to the view, so it's recognizing the collection. Add locals: { comment: @comment, post: @post }
still gets me undefined local variable post for Class, and post: @comment.post
gets a nilClass error. I've been all over SO and the RoR Guides backwards and forwards on rendering partials, and I'm still very unclear on what to pass when, so any help there in general is appreciated.
Upvotes: 0
Views: 370
Reputation: 727
Different perspective you just need to change post.id
to comment.post.id
in _comment.html.erb without pass locals
, it more clearner and simple
<div class="comment" id="comment-<%= comment.post.id %>-<%= comment.id %>">
<%= link_to smavatar_for(comment.user), user_path(comment.user.name) %>
<span class="user"><%= link_to comment.user.name, user_path(comment.user.name) %></span>
<div class="comment-content">
<%= simple_format(comment.content) %>
</div>
</div>
does it work?
Upvotes: 0
Reputation: 7434
Post
from the Comment
itselfAssuming every Comment
has a belongs_to :post
association
Call the partial using the shortcut syntax exactly as you had
<%= render @comments.last(3) %>
Inside the partial, use comment.post
or comment.post_id
to get Post
data
E.g.
<div class="comment" id="comment-<%= comment.post_id %>-<%= comment.id %>">
<%= link_to smavatar_for(comment.user), user_path(comment.user.name) %>
<span class="user"><%= link_to comment.user.name, user_path(comment.user.name) %></span>
<div class="comment-content">
<%= simple_format(comment.content) %>
</div>
</div>
locals
in this scenarioNotice that you tried to pass @post
in through the locals
option, however in your controller you have a @posts
variable (plural), not @post
singular.
Because each of the Comment
records may belong to a different Post
, there is no single option you can pass for Post
.
The only other way to use locals
is if you broke out the partial into a loop and rendered each Comment
individually, e.g.
<% @comments.last(3).each do |comment| %>
<%= render comment, post: comment.post %>
<!-- OR -->
<%= render partial: "comments/comment", locals: { comment: comment, post: comment.post } %>
<% end %>
Notice we still need to call comment.post
to get the Post
associated with the Comment
. Because of this, it's much simpler to just use the shortcut syntax and reference the Post
from the Comment
within the partial.
Upvotes: 2