如何在Rails 5 ActiveRecord中执行or
查询?同时,是否可以在ActiveRecord查询中使用where
链接or
?
如何在Rails 5 ActiveRecord中执行or
查询?同时,是否可以在ActiveRecord查询中使用where
链接or
?
or
条款与where
条款链接在一起来进行ActiveRecord
查询。请参阅相关讨论和Pull请求。因此,在Rails 5中,您可以执行以下操作:获取id
为1或2的post
:Post.where('id = 1').or(Post.where('id = 2'))
其他一些例子:
(A && B) || C:
Post.where(a).where(b).or(Post.where(c))
(A || B) && C:
Post.where(a).or(Post.where(b)).where(c)
Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))
这样可以创建 (a || b) && (c || d)。 - engineersmnkyArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
。 - Suan.or
并且生成 and
的是 .merge
。可以通过 Post.where(a).or(Post.where(b)).merge(Post.where(c).or(Post.where(d)))
来生成 (A || B) && (C || D)
。 - Siim Liisermerge
是从哪里来的?如果是 Array#merge
,那对我没用,因为我想要执行单个查询。而且还希望能够将整个内容作为关系传递。 - Mathieu J.scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
我需要执行以下操作:(A && B) || (C && D) || (E && F)
但是在Rails 5.1.4
的当前状态下,使用Arel或运算符链来实现这个操作变得太过复杂。但是我仍然想尽可能多地使用Rails来生成查询语句。
所以我进行了一个小小的hack:
在我的模型中,我创建了一个名为sql_where
的私有方法:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
scope :whatever, -> {
ors = []
ors << sql_where(A, B)
ors << sql_where(C, D)
ors << sql_where(E, F)
# Now just combine the stumps:
where(ors.join(' OR '))
}
下面的查询语句可以得到预期的查询结果:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
现在,我可以轻松地将其与其他作用域组合使用,而不会产生错误的 OR 操作符。
优美之处在于,我的 sql_where 接受普通的 where 子句参数:sql_where(name: 'John', role: 'admin')
会生成 (name = 'John' AND role = 'admin')
。
.merge
代替&&
,并构建一个合适的树来捕获你的括号。像这样:(scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
,假设每个作用域看起来像Model.where(...)
。 - nar8789where
的or
语句的能力。
例如:User.where(name: "abc").or(User.where(name: "abcd"))