3

我有这两段代码,每段代码都返回 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

有没有办法做到这一点?

4

1 回答 1

1

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

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

于 2012-09-07T03:55:38.663 回答