检索给定用户评论的所有post,Ruby on Rails

我有用户,post和评论。 用户只能在每个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 

在用户页面上(例如, http://host/users/1 )我想显示给定用户评论过的所有post。 然后每个post都会有所有其他评论。

我可以在我的用户控制器中执行以下操作:

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

通过这种方式,我会找到User,然后是他的所有评论,然后是每个评论的相应post,然后(在我看来)每个post我将呈现post.comments。 我是Rails中的新手,所以我可以做到这一点=)但我认为它有点不好而且有更好的方法来做到这一点,也许我应该使用范围或named_scopes(不知道这是什么,但看起来害怕)。

所以你能指出我在正确的方向吗?

您可以定义一个关联,该关联在单个查询中检索包含注释的所有post。 将其保留在模型中可以降低控制器的复杂性,使您能够重用关联并使unit testing更容易。

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

:throughhas_many一个选项,用于指定用于执行查询的连接表。 我们需要指定:source因为Rails无法从:post_with_comments推断源。

最后,更新您的控制器以使用该关联。

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

要了解更多关于:through:source请查看文档 。

获得用户后,您就可以获得他的post的关联,每个post都有他的评论。 你可以写:(我不知道你的表字段的名称,所以我命名文本文本)

 # 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 

我没有测试过代码,所以可能会出现一些错误。