背景:我在 edge Rails (4.1.0.rc1) 上。用户通过 CommunityUser 模型拥有多个社区。以下用户属于各个社区:
USERS TABLE
ID | COMMUNITY_IDS
---|--------------
1 | [2, 7, 8]
2 | [3, 4, 8]
3 | [4, 5, 7]
4 | [3, 5, 7]
5 | [3, 8, 10]
6 | [4, 6, 7]
7 | [1, 8, 10]
8 | [3, 8, 10]
9 | [2, 9, 10]
10 | [3, 6, 10]
User.joins(:communities).where(communities: {id: [5,7]}).uniq
Returns all users associated with either Community 5 or Community 7:
SQL => SELECT DISTINCT "users".* FROM "users" INNER JOIN "community_users" ON "community_users"."user_id" = "users"."id" INNER JOIN "communities" ON "communities"."id" = "community_users"."community_id" WHERE "communities"."id" IN (5, 7)
ID | COMMUNITY_IDS
---|--------------
1 | [2, 7, 8]
3 | [4, 5, 7]
4 | [3, 5, 7]
6 | [4, 6, 7]
尝试通过添加另一个返回空 ActiveRecord::Relation 的 where 子句来进一步过滤这些(返回该组中也与社区 6 关联的那些):
User.joins(:communities).where(communities: {id: [5,7]}).where(communities: {id: [6]}).uniq
=> SQL: SELECT DISTINCT "users".* FROM "users" INNER JOIN "community_users" ON "community_users"."user_id" = "users"."id" INNER JOIN "communities" ON "communities"."id" = "community_users"."community_id" WHERE "communities"."id" IN (5, 7) AND "communities"."id" IN (6)
=> #<ActiveRecord::Relation []>
目标:这是该查询的正确行为吗?如果是这样,我将如何编写此查询以返回与 EITHER 社区 5 相关联的用户或与社区 6 相关联的社区 7 AND 的用户。
最佳答案
问题是您以上面显示的方式考虑 community_ids。
ID | COMMUNITY_IDS
---|--------------
1 | [2, 7, 8]
3 | [4, 5, 7]
4 | [3, 5, 7]
6 | [4, 6, 7]
实际上,您会得到这个中间结果集:
UID| COMMUNITY_ID
---|--------------
3 | 5
4 | 5
1 | 7
3 | 7
4 | 7
6 | 7
然后你说:好的,还有 (6) 中的“communities”.“id”! 结果集中没有具有该 id 的社区。p>
通过社区 [5,7] 吸引用户:
users = Community.where(id:[5,7]).map(&:users).flatten.uniq
按 id=7 的社区过滤用户:
filtered = users.select{|u| u.communities.map(&:id).include?(6) }
此代码有效(它返回包含 id = 6 的单个用户的数组) 但这不是最好的解决方案。
关于mysql - 在 has_many 上链接 where 子句 :through association (Rails 4. 1.0.rc1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22287381/