[英]Rails, query with Active record does not take into account negative where condition
I have the following data model:我有以下数据 model:
user has_many organization_users
user has_many registrations
a user has a column type
a registration has columns learning_item_type and learning_item_id
The goal of the query is to retrieve all users from a specific organization that dont have registrations to a specific learning item (combinaison of learning_item_type and learning_item_id), it must include users from the organizations that don't have registrations at all (left join) I came up with this with active record query:查询的目标是检索特定组织中没有注册特定学习项目的所有用户(learning_item_type 和 learning_item_id 的组合),它必须包括根本没有注册的组织中的用户(左连接)我想出了这个与活动记录查询:
User
.joins(:organizations_users)
.left_joins(:registrations)
.where(
type: 'Collaborator',
'organizations_users.organization_id': organization.id
)
.where.not(
'registrations.learning_item_id': learning_item.id,
'registrations.learning_item_type': learning_item.class.to_s
).distinct
which in raw sql looks like:在原始 sql 中看起来像:
"SELECT DISTINCT \"users\".* FROM \"users\" INNER JOIN \"organizations_users\" ON \"organizations_users\".\"user_id\" = \"users\".\"id\" LEFT OUTER JOIN \"registrations\" ON \"registrations\".\"account_id\" = 28 AND \"registrations\".\"user_id\" = \"users\".\"id\" WHERE \"users\".\"account_id\" = 28 AND \"users\".\"type\" = 'Collaborator' AND \"organizations_users\".\"organization_id\" = 1 AND NOT (\"registrations\".\"learning_item_id\" = 10164 AND \"registrations\".\"learning_item_type\" = 'Session')"
I can't figure out what's wrong with this query but it keeps returning users who actually have a registration with learning_item_id = 10164 and learning_item_type 'Session'.我不知道这个查询有什么问题,但它会不断返回实际注册 learning_item_id = 10164 和 learning_item_type 'Session' 的用户。
Why is that negative NOT criteria not taken into account here?为什么这里没有考虑否定的非标准?
User.left_joins(:registrations)
After the join you get something like this:加入后你会得到这样的东西:
users.id![]() |
registrations.learning_item_id ![]() |
---|---|
1 ![]() |
10164 ![]() |
1 ![]() |
10165 ![]() |
2 ![]() |
10166 ![]() |
Then filter out learning item 10164
:然后过滤掉学习项
10164
:
User.left_joins(:registrations)
.where.not("registrations.learning_item_id": 10164)
Result is:结果是:
users.id![]() |
registrations.learning_item_id ![]() |
---|---|
1 ![]() |
10165 ![]() |
2 ![]() |
10166 ![]() |
The returned sql result is correct, but you still get User#1
that is registered to LearningItem#10164
.返回的 sql 结果是正确的,但您仍然会得到注册到
LearningItem#10164
的User#1
。
What you need is to filter out the user:您需要的是过滤掉用户:
User.where.not(
id: User.joins(:registrations).where("registrations.learning_item_id": 10164)
)
users.id![]() |
registrations.learning_item_id ![]() |
---|---|
2 ![]() |
10166 ![]() |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.