我正在构建一个约会风格的应用,其中User
可以批准其他用户。
我使用Approval
模型来跟踪这些关系。每个Approval
都有一个user_id
和一个approved_id
- 已批准User
的用户ID。它还有rejected_at
,表示一个User
拒绝了另一个的日期时间。
要向符合条件的用户提供current_user
,我必须查询有
Approval
关系Approval
仅与approved_id
关系current_user.id
(意味着符合条件的用户批准current_user,但相反没有关系User
Approval
rejected_at
个approved_id
属User
属user_id
为current_user
或joins
的{{1}} Approval
。如何制作ActiveRecord查询以查找符合条件的用户?我知道我可以Approval
User
<select name="formBook">
have to become:
<select name="formBook[]" multiple">
,但我也想说明if(isset($_POST['formSubmit']))
{
$sum = array_sum($_POST['formBook']); // Sum of all selected elements
...
}
之间没有{{1}}关系!我认为只做两个单独的查询可能更有意义,但我想知道它是否可以组合成一个......
答案 0 :(得分:6)
您需要的行为是LEFT OUTER JOIN,其中包含来自users
的行,无论approvals
中是否有匹配的行。这样,您就会得到一个User
未发出关于您的目标Approval
的{{1}},或者一个已经过我们可以过滤拒绝的人。{/ p>
The query看起来像
User
分片,
-- Looking for users who either have no opinion or have approved user 1
SELECT *
FROM users
LEFT OUTER JOIN approvals
ON users.id = approvals.user_id
AND approvals.approved_id = 1 -- Filter for only approvals of user 1
WHERE users.id != 1 -- Ignore user 1
AND (
approvals.approved_id IS NULL -- Approving user has no opinion of user 1
OR approvals.rejected_at IS NULL -- Approving user has not rejected user 1
)
;
会考虑所有users LEFT OUTER JOIN approvals
,即使他们没有users
approvals
与他们创建的ON users.id = approvals.user_id
users
对approvals
仅考虑ON ... AND approvals.approved_id = 1
approvals
User 1
仅考虑其他WHERE users.id != 1
users
需要WHERE ... approvals.approved_id IS NULL
尚未创建与users
相关的任何approvals
。User 1
需要WHERE ... approvals.rejected_at IS NULL
为users
创建Approval
,这不是拒绝 User 1
并没有做任何特别漂亮的事情,但它确实有效:
ActiveRecord
如果您想要更具可读性的内容,可以收集拒绝某个人的每个class User < ActiveRecord::Base
def eligible_partners
User.joins( # Join like we did before
<<-SQL
LEFT OUTER JOIN approvals
ON users.id = approvals.user_id
AND approvals.approved_id = #{self.id}
SQL
).where.not(id: id) # Ignore ourselves
.where( # Filter for no approvals or a positive approval
<<-SQL
approvals.approved_id IS NULL
OR approvals.rejected_at IS NULL
SQL
)
end
end
的ID,然后获取所有其他User
个。一方面,这是两个问题;另一方面,一旦你的牌桌变大,它可能比User
便宜,而且它更容易理解。
JOIN