DatingApp编程:ActiveRecord关联,用于查找没有批准或单向批准的用户

时间:2015-07-07 19:20:56

标签: ruby-on-rails postgresql activerecord

我正在构建一个约会风格的应用,其中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_atapproved_idUseruser_idcurrent_userjoins的{​​{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}}关系!我认为只做两个单独的查询可能更有意义,但我想知道它是否可以组合成一个......

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