Question

I am trying to wrap my head around this problem. I know views shouldn't have that much logic in them. I have an app with users, posts and comments. Users have many posts and comments.

class User < ActiveRecord::Base
has_many :posts
has_many :comments

Posts belong to users and have many comments.

class Post < ActiveRecord::Base
has_many :comments
belongs_to :user

Comments belong to users and posts

class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user

In my post#show view I show comments under the post. I want to show the name of the user who made the comment. At the moment I have this in my view:

<% @post.comments.each do |comment| %>
  <p>
    <b>Commenter:</b>
    <%= link_to  User.find(comment.userid).login, User.find(comment.userid) %>
  </p>

  <p>
    <b>Comment:</b>
    <%= comment.body %>
  </p>
<% end %>

I should probably have that logic in my posts controller. But I am pretty confused. @post.comments returns an array(?) of comments belonging to the post. That means I can't have @commenter = @post.comments.userid. I am confused by the problem so I might not have explained it well.

Was it helpful?

Solution

In fact during the comments loop, you can use comment.user to get the data of the user since you have declared the User has_many Comments relationship.

OTHER TIPS

To be more explicit on the first answer, you simply do this:

<%= link_to comment.user, comment.user %>

In your User model, override the to_s method like this so comment.user returns the string you want:

def to_s
  self.login
end

Finally, use eager loading to get all the data in one SQL call, instead of querying the DB separately for each comment.user. In your Post model:

class Post < ActiveRecord::Base
  has_many :comments, :include => :user

And in the Post controller:

def show
  @post = Post.find(params[:id], :include => :comments)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top