Database Rails 3-列出当前用户尚未加入的组
我正在将一个应用程序从php转换为rails,我还在学习如何使用rails和AR 简单地说:我想列出当前用户尚未加入的组 失败的方法: 原因。选择“原因。*”。加入:users.group“causs.id”。wherecause\u user\u memberships.user\u id 不在,当前_user.id 原因。选择“原因。*”。加入:users.group“原因.id”。其中原因\u user\u memberships.user\u id不在选择原因\u user\u memberships.Cause\u id来自原因\u user\u memberships,其中原因\u user\u memberships.user\u id=,当前\u user.id 还有很多。。。 谢谢你的帮助 关于模型的一些信息 User.rb代码段 原因.rb Cause_User_Membership.rb在rails中,joins:symbol语句变成了一个内部连接,不适合查找不存在的关系。可以手动写入联接,使其成为左联接:Database Rails 3-列出当前用户尚未加入的组,database,ruby-on-rails-3,postgresql,activerecord,Database,Ruby On Rails 3,Postgresql,Activerecord,我正在将一个应用程序从php转换为rails,我还在学习如何使用rails和AR 简单地说:我想列出当前用户尚未加入的组 失败的方法: 原因。选择“原因。*”。加入:users.group“causs.id”。wherecause\u user\u memberships.user\u id 不在,当前_user.id 原因。选择“原因。*”。加入:users.group“原因.id”。其中原因\u user\u memberships.user\u id不在选择原因\u user\u memb
Cause.joins("""
LEFT JOIN cause_user_memberships
ON cause_user_memberships.cause_id = causes.id
AND cause_user_memberships.user_id = #{current_user.id}
""").where("cause_user_memberships.id IS NULL")
更新
内部联接将阻止创建一组没有映射到给定用户的原因。例如:
Causes
id | name
============
1 | Cause 1
2 | Cause 2
Users
id | name
============
1 | User 1
Cause User Memberships
id | user_id | cause_id
=======================
1 | 1 | 1
SELECT *
FROM causes
INNER JOIN cause_user_memberships
ON cause_user_memberships.cause_id = causes.id
AND cause_user_memberships.user_id = 1
会回来的
causes.id | causes.name | cause_user_memberships.id | cause_user_memberships.user_id | cause_user_memberships.cause_id
===========================================================================================================================
1 | Cause 1 | 1 | 1 | 1
causes.id | causes.name | cause_user_memberships.id | cause_user_memberships.user_id | cause_user_memberships.cause_id
===========================================================================================================================
1 | Cause 1 | 1 | 1 | 1
2 | Cause 2 | null | null | null
为了找出用户不属于的原因,您不能再对其执行任何逻辑
SELECT *
FROM causes
LEFT JOIN cause_user_memberships
ON cause_user_memberships.cause_id = cause.id
AND cause_user_memberships.user_id = 1
会回来的
causes.id | causes.name | cause_user_memberships.id | cause_user_memberships.user_id | cause_user_memberships.cause_id
===========================================================================================================================
1 | Cause 1 | 1 | 1 | 1
causes.id | causes.name | cause_user_memberships.id | cause_user_memberships.user_id | cause_user_memberships.cause_id
===========================================================================================================================
1 | Cause 1 | 1 | 1 | 1
2 | Cause 2 | null | null | null
在这种情况下,所有原因都将获得一行,无论它们是否匹配原因用户成员资格表中的记录。现在,您可以应用附加条件来梳理用户不属于的原因,其中cause\u user\u membership.id为null。他的关系确实存在,他有一个has\u many:users,因此连接应该可以工作。否?@LeoCorrea主要问题是内部连接。它无法返回不存在的原因\用户\成员记录。我将在我的答案中添加更多内容。谢谢你的帮助。快速后续左上连接通常比内部连接慢。通过在联接表的cause_id和user_id列上应用索引,您可能会看到一些改进。在显示Seq Scan的查询计划中,这意味着postgres只是在表中循环,直到找到结果。感谢您的建议。我今晚就做。1000米看起来不是太长了吗?当我用php/MySQL做了几乎相同的事情,并且没有活动记录时,速度会快几个数量级。我摸不着头脑为什么会有这么大的差异。它看起来确实有点长。但是有很多变数。ActiveRecord在内存中构建对象的副本,因此存在与查询速度没有直接关系的开销。您可以在SQL控制台(如pgAdmin)中检查查询,以便将ActiveRecord作为变量删除。
Causes
id | name
============
1 | Cause 1
2 | Cause 2
Users
id | name
============
1 | User 1
Cause User Memberships
id | user_id | cause_id
=======================
1 | 1 | 1
SELECT *
FROM causes
INNER JOIN cause_user_memberships
ON cause_user_memberships.cause_id = causes.id
AND cause_user_memberships.user_id = 1
causes.id | causes.name | cause_user_memberships.id | cause_user_memberships.user_id | cause_user_memberships.cause_id
===========================================================================================================================
1 | Cause 1 | 1 | 1 | 1
SELECT *
FROM causes
LEFT JOIN cause_user_memberships
ON cause_user_memberships.cause_id = cause.id
AND cause_user_memberships.user_id = 1
causes.id | causes.name | cause_user_memberships.id | cause_user_memberships.user_id | cause_user_memberships.cause_id
===========================================================================================================================
1 | Cause 1 | 1 | 1 | 1
2 | Cause 2 | null | null | null