问题
Given
Document:
has_many :shares
has_many :groups, :through => :shares
User:
has_many :memberships
has_many :groups, :through => :memberships
Group:
has_many :memberships
has_many :users, :through => :memberships
has_many :shares
has_many :documents, :through => :shares
I need to show only documents for a given instance of User, current_user.
@documents = current_user.groups.documents
doesn't cut it.
How can i filter down to only the documents that have at least on group in common with the user?
回答1:
You can do this with a single query:
Document.includes(:shares => { :group => :users }).where('users.id' => current_user.id)
Generated SQL (for 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
Note that by using includes instead of joins, only distinct results are returned (so no need to call uniq
on the result). See: Distinct Join Rails
回答2:
What about
docs = []
current_user.groups.uniq.each do |group|
docs << group.documents
end
docs
来源:https://stackoverflow.com/questions/13514073/filter-model-with-multiple-has-many-through