2012-11-22 102 views
0

鑑於篩選模型與多個有很多通過

文件:

has_many :shares 
has_many :groups, :through => :shares 

用戶:

has_many :memberships 
has_many :groups, :through => :memberships 

組:

has_many :memberships 
has_many :users, :through => :memberships 

has_many :shares 
has_many :documents, :through => :shares 

我需要證明的唯一證件給出User,current_user的實例。

@documents = current_user.groups.documents不會削減它。

我如何過濾只有至少與用戶共同組的文檔?

回答

1

您可以使用單個查詢做到這一點:

Document.includes(:shares => { :group => :users }).where('users.id' => current_user.id) 

生成的SQL(爲current_user.id = 1):

SELECT "documents"."id" AS t0_r0, "documents"."created_at" AS t0_r1, 
    "documents"."updated_at" AS t0_r2, "shares"."id" AS t1_r0, 
    "shares"."group_id" AS t1_r1, "shares"."document_id" AS t1_r2, 
    "shares"."created_at" AS t1_r3, "shares"."updated_at" AS t1_r4, 
    "groups"."id" AS t2_r0, "groups"."created_at" AS t2_r1, 
    "groups"."updated_at" AS t2_r2, "users"."id" AS t3_r0, 
    "users"."created_at" AS t3_r1, "users"."updated_at" AS t3_r2 
    FROM "documents" 
    LEFT OUTER JOIN "shares" ON "shares"."document_id" = "documents"."id" 
    LEFT OUTER JOIN "groups" ON "groups"."id" = "shares"."group_id" 
    LEFT OUTER JOIN "memberships" ON "memberships"."group_id" = "groups"."id" 
    LEFT OUTER JOIN "users" ON "users"."id" = "memberships"."user_id" 
    WHERE "users"."id" = 1 

注意,通過使用includes代替joins,只返回不同的結果(所以無需在結果上調用uniq)。請參閱:Distinct Join Rails

+0

問題與做法是,如果一個文件有2組共同與用戶其輸出文檔的2倍。添加.uniq到最後修復它,但我不確定這是獲得結果的最佳方式。無論如何,感謝您的輸入! –

+0

我同意用更簡潔的方式做它會很好,但性能方面的關鍵問題是它對數據庫的查詢。通過這種方法,您可以得到兩個,首先找到與'current_user'關聯的組(通過'memberships'),然後選擇具有這些組的所有文檔(通過'shares')。這是達到理想效果所需的最低限度。 –

+0

更新了我的答案:您可以使用單個數據庫查詢來完成此操作。 –

0

什麼

docs = [] 
current_user.groups.uniq.each do |group| 
    docs << group.documents 
end 
docs