[英]In Rails, how do I query two has_many associations in a single finder?
I'm using Rails 4.2.我正在使用 Rails 4.2。 I have the following user model with a couple of has_many associations
我有以下用户 model 有几个 has_many 关联
class User < ActiveRecord::Base
…
has_many :roles, through: :roles_users
has_many :addresses, dependent: :destroy, as: :addressable, inverse_of: :addressable
I would like to find all users of a specific role without any addresses.我想找到没有任何地址的特定角色的所有用户。 I thought the below would do it
我以为下面会做到这一点
> users = User.includes(:roles, :addresses).where(:roles => {:name => 'User'}, :addresses => {:user_id => nil})
But when I check the results, I'm still getting results that have addresses …但是当我检查结果时,我仍然得到有地址的结果......
2.7.1 :012 > users.last.addresses.count
…
=> 2
What's the proper way to write a finder that queries these two has_many associations?编写查询这两个 has_many 关联的查找器的正确方法是什么?
Checking for children records with a nil parent id is like the way of doing this in Rails 4. But if that doesn't work, you could use the NOT IN clause combination:检查具有 nil 父 ID 的子记录就像在 Rails 4 中执行此操作的方式一样。但是如果这不起作用,您可以使用 NOT IN 子句组合:
User
.where
.not(
id: User
.joins(:addresses, :roles)
.where(roles: { name: 'User' })
.select(:id)
)
It's basically filtering out by the user id all those user rows that have an address associated, have a role, and the role name is exactly "User".它基本上是通过用户 ID 过滤掉所有具有关联地址、具有角色且角色名称恰好是“用户”的用户行。 You end up with a SQL query like this:
您最终会得到一个 SQL 查询,如下所示:
SELECT "users".*
FROM "users"
WHERE "users"."id" NOT IN (
SELECT "users"."id"
FROM "users"
INNER JOIN "roles_users" ON "roles_users"."user_id" = "users"."id"
INNER JOIN "roles" ON "roles"."id" = "roles_users"."role_id"
WHERE "roles"."name" = 'User'
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.