Retrieve all posts where the given user has commented, Ruby on Rails

我与影子孤独终老i 提交于 2019-12-09 07:12:53

问题


I have users, posts and comments. User can post only one comment to each post.

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

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

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

On userpage (http://host/users/1 for example) I want to show all posts where the given user has commented. Each post then will have all other comments.

I can do something like this in my User controller:

def show
  @user = User.find(params[:user_id])
  @posts = []
  user.comments.each {|comment| @posts << comment.post}
end

This way I will find User, then all his comments, then corresponding post to each comment, and then (in my view) for each post I will render post.comments. I'm totally new in Rails, so I can do this =) But I think it's somehow bad and there is a better way to do this, maybe I should use scopes or named_scopes (don't know yet what this is, but looks scary).

So can you point me out to the right direction here?


回答1:


You could define an association which retrieves all the posts with comments in a single query. Keeping it in the model reduces the complexity of your controllers, enables you to reuse the association and makes it easier to unit test.

class User < ActiveRecord::Base
  has_many :posts_with_comments, :through => :comments, :source => :post
  # ...
end

:through is an option for has_many to specify a join table through which to perform the query. We need to specify the :source as Rails wouldn't be able to infer the source from :post_with_comments.

Lastly, update your controller to use the association.

def show
  @user  = User.find(params[:user_id])
  @posts = @user.posts_with_comments
end

To understand more about :through and :source take a look at the documentation.




回答2:


When you got the user, you have the associations to his posts and each post has his comments. You could write: (I don't know the names of your table fields, so i named the text text)

# In Controller
@user = User.find(params[:user_id]).include([:posts, :comments])

# In View
@user.posts.each do |post|
  post.text
  # Comments to the Post
  post.comments.each do |comment|
    comment.text
  end
end

I haven't tested the code, so there could be some errors.



来源:https://stackoverflow.com/questions/4004150/retrieve-all-posts-where-the-given-user-has-commented-ruby-on-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!