【问题标题】:Merge 2 relations on OR instead of AND在 OR 而不是 AND 上合并 2 个关系
【发布时间】:2012-09-07 02:32:38
【问题描述】:

我有这两段代码,每段代码都返回 Micropost 模型中的一个关系。

scope :including_replies, lambda { |user| where("microposts.in_reply_to = ?", user.id)}

def self.from_users_followed_by(user)
  followed_user_ids = user.followed_user_ids
  where("user_id IN (?) OR user_id = ?", followed_user_ids, user)
end

当我运行 r1 = Micropost.including_replies(user) 时,我使用以下 SQL 得到两个结果的关系:

SELECT `microposts`.* FROM `microposts` WHERE (microposts.in_reply_to = 102) ORDER BY 
microposts.created_at DESC

当我运行 r2 = Micropost.from_users_followed_by(user) 时,我得到一个与以下 SQL 的结果的关系:

SELECT `microposts`.* FROM `microposts` WHERE (user_id IN (NULL) OR user_id = 102) ORDER 
BY microposts.created_at DESC

现在,当我像 r3 = r1.merge(r2) 这样合并关系时,我得到了零个结果,但期待三个。原因是 SQL 看起来像这样:

SELECT `microposts`.* FROM `microposts` WHERE (microposts.in_reply_to = 102) AND 
(user_id IN (NULL) OR user_id = 102) ORDER BY microposts.created_at DESC

现在我需要的是(microposts.in_reply_to = 102) OR (user_id IN (NULL) OR user_id = 102) 在合并关系中,我需要 OR 而不是 AND

有没有办法做到这一点?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord


    【解决方案1】:

    不直接使用 Rails。 Rails 没有公开任何将 ActiveRelation(作用域)对象与OR 合并的方法。原因是 ActiveRelation 可能不仅包含条件(WHERE 子句中描述的内容),还可能包含与 OR 合并的未明确定义的连接和其他 SQL 子句。

    您可以直接使用 Arel(ActiveRelation 建立在其之上)来执行此操作,也可以使用 Squeel,它通过 DSL 公开 Arel 功能(这可能更方便)。对于 Squeel,ActiveRelations 不能被合并仍然是相关的。但是 Squeel 还提供了Sifters,它表示您可以使用的条件(没有任何其他 SQL 子句)。不过,这将涉及将范围重写为筛选器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 2018-03-17
      • 2019-10-30
      • 2010-12-01
      • 2022-01-07
      • 1970-01-01
      • 2012-05-31
      相关资源
      最近更新 更多