Rails 5: ActiveRecord OR 查询
Rails 5: ActiveRecord OR query
如何在 Rails 5 ActiveRecord 中执行 or
查询?此外,是否可以在 ActiveRecord 查询中将 or
与 where
链接起来?
在 ActiveRecord
查询中将 or
子句与 where
子句链接起来的能力将在 Rails 中可用 5 。见 related discussion and the pull request.
因此,您将能够在 Rails 5:
中执行以下操作
要获得 post
id
1 或 2:
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)
我们不需要等待 rails 5 来使用这个 OR
查询。我们也可以将它与 rails 4.2.3
一起使用。有一个向后移植 here.
感谢 Eric-Guo for gem where-or,现在我们可以在 >= rails 4.2.3
中添加 OR
功能,也可以使用 gem.
我需要做一个 (A && B) || (C && D) || (E && F)
但在 Rails 5.1.4
的当前状态下,使用 Arel or-chain 无法完成此操作。
但我仍然想使用 Rails 生成尽可能多的查询。
所以我做了一个小技巧:
在我的模型中,我创建了一个名为 sql_where
:
的 private 方法
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
接下来在我的范围内我创建了一个数组来保存 OR
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-clause 参数:
sql_where(name: 'John', role: 'admin')
将生成 (name = 'John' AND role = 'admin')
.
(只是对 K M Rakibul Islam 的回答的补充。)
使用范围,代码可以变得更漂亮(取决于眼睛看起来):
scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
Rails 5 有能力 or
从句 where
。
例如。
User.where(name: "abc").or(User.where(name: "abcd"))
如何在 Rails 5 ActiveRecord 中执行 or
查询?此外,是否可以在 ActiveRecord 查询中将 or
与 where
链接起来?
在 ActiveRecord
查询中将 or
子句与 where
子句链接起来的能力将在 Rails 中可用 5 。见 related discussion and the pull request.
因此,您将能够在 Rails 5:
中执行以下操作要获得 post
id
1 或 2:
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)
我们不需要等待 rails 5 来使用这个 OR
查询。我们也可以将它与 rails 4.2.3
一起使用。有一个向后移植 here.
感谢 Eric-Guo for gem where-or,现在我们可以在 >= rails 4.2.3
中添加 OR
功能,也可以使用 gem.
我需要做一个 (A && B) || (C && D) || (E && F)
但在 Rails 5.1.4
的当前状态下,使用 Arel or-chain 无法完成此操作。
但我仍然想使用 Rails 生成尽可能多的查询。
所以我做了一个小技巧:
在我的模型中,我创建了一个名为 sql_where
:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
接下来在我的范围内我创建了一个数组来保存 OR
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-clause 参数:
sql_where(name: 'John', role: 'admin')
将生成 (name = 'John' AND role = 'admin')
.
(只是对 K M Rakibul Islam 的回答的补充。)
使用范围,代码可以变得更漂亮(取决于眼睛看起来):
scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
Rails 5 有能力 or
从句 where
。
例如。
User.where(name: "abc").or(User.where(name: "abcd"))