How can I remove this logic from my view?
-
05-10-2019 - |
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.
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)