2014-02-26 65 views
0

我有一些車型嵌套ActiveRecord的關係,Rails的

class User < ActiveRecord::Base 
    belongs_to :group 
end 

class Group < ActiveRecord::Base 
    has_many :users 
    has_many :posts 
end 

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

class Comment < ActiveRecord::Base 
    belongs_to :post 
end 

要獲得用戶的職位,我可以做User.find(1).group.posts.all,但是如果我想爲用戶帖子所有評論我做不到User.find(1).group.posts.all.comments.all

有沒有簡單的解決方案,得到了用戶的帖子不是通過所有的職位循環其他所有評論?

+0

根據Sævar在我的回答下面的評論我認爲這是一個好主意,指出User.find(1).group.p osts檢索用戶組中的所有帖子,而不僅僅是該用戶所做的。那是你要的嗎? – Coenwulf

回答

1

單查詢解決方案:

Comment.joins(post: {group: :users}).where(users: {id: 1}) 

結果查詢:

SELECT "comments".* FROM "comments" 
    INNER JOIN "posts" ON "posts"."id" = "comments"."post_id" 
    INNER JOIN "groups" ON "groups"."id" = "posts"."group_id" 
    INNER JOIN "users" ON "users"."group_id" = "groups"."id" 
    WHERE "users"."id" = 1 
2

你想要的是通過關係的has_many:http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

以下內容添加到您的組類

has_many :comments, through: :posts 

然後你就可以得到與評論:

User.find(1).group.comments 
+0

這會爲您提供用戶組的所有評論,而不是針對屬於指定用戶的帖子的評論。 –

+0

好點,但基於OP獲得帖子的方式(User.find(1).group.posts)我認爲這是所需的行爲。如果不是,則需要更改數據庫結構。 – Coenwulf

+0

好吧,OP說:「爲用戶的帖子獲取所有評論」,所以這就是我所設想的。數據庫結構很好,訣竅是提出一個有效的查詢。 –

-1

簡單地增加has_many :comments, through: :posts是不夠的。 然後,像User.find(1).group.comments這樣的查詢將爲您提供用戶組的所有評論,而不是指定的用戶。

另一種方式是查找所有帖子的ID的給定用戶,並用它來查找該用戶的帖子評論:

post_ids = User.find(1).group.posts.map(&:id).uniq 
user_comments = Comment.where(:post => post_ids) 
+0

這將激發每個帖子的查詢,這是非常低效的。這就是所謂的一個N + 1查詢,請參閱http://stackoverflow.com/questions/97197/what-is-the-n1-selects-issue –

+1

不,這實際上導致3個SQL查詢。一個選擇用戶。然後像這樣選擇基於用戶組的帖子:從posts.group_id = 1的帖子中選擇帖子。*第三個使用如下查詢選擇註釋:SELECT comments。* from comments where where.post_id IN [ 1,2,3,4,5] –

+0

你說得對,對不起。但是,這仍然會表現不佳,因爲您必須將數據庫中的值讀取到Ruby中,以便將它們重新放回以選擇註釋而不是JOIN。 –