Ruby-on-rails 如何使用 OR 而不是 AND 链接范围查询?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3684311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to chain scope queries with OR instead of AND?
提问by user410715
I'm using Rails3, ActiveRecord
我正在使用 Rails3,ActiveRecord
Just wondering how can I chain the scopes with OR statements rather than AND.
只是想知道如何使用 OR 语句而不是 AND 来链接作用域。
e.g.
例如
Person.where(:name => "John").where(:lastname => "Smith")
That normally returns:
通常会返回:
name = 'John' AND lastname = 'Smith'
but I'd like:
但我想:
`name = 'John' OR lastname = 'Smith'
回答by Petros
You would do
你会做
Person.where('name=? OR lastname=?', 'John', 'Smith')
Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).
现在,新的 AR3 语法没有任何其他 OR 支持(即不使用某些 3rd 方 gem)。
回答by Ryan Leaf
According to this pull request, Rails 5 now supports the following syntax for chaining queries:
根据这个 pull request,Rails 5 现在支持以下用于链接查询的语法:
Post.where(id: 1).or(Post.where(id: 2))
There's also a backport of the functionality into Rails 4.2 via this gem.
回答by Dan McNevin
回答by daino3
Just posting the Array syntax for samecolumn OR queries to help peeps out.
只需发布同一列 OR 查询的 Array 语法以帮助窥视。
Person.where(name: ["John", "Steve"])
回答by kissrobber
Update for Rails4
Rails4 更新
requires no 3rd party gems
不需要第 3 方宝石
a = Person.where(name: "John") # or any scope
b = Person.where(lastname: "Smith") # or any scope
Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))\
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
Old answer
旧答案
requires no 3rd party gems
不需要第 3 方宝石
Person.where(
Person.where(:name => "John").where(:lastname => "Smith")
.where_values.reduce(:or)
)
回答by Simon Perepelitsa
回答by codenamev
In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.
如果有人正在寻找此问题的更新答案,似乎有一个现有的拉取请求可以将其放入 Rails:https: //github.com/rails/rails/pull/9052。
Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:
感谢@j-mcnally 的 ActiveRecord 猴子补丁(https://gist.github.com/j-mcnally/250eaaceef234dd8971b),您可以执行以下操作:
Person.where(name: 'John').or.where(last_name: 'Smith').all
Even more valuable is the ability to chain scopes with OR:
更有价值的是将范围链接到以下内容的能力OR:
scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }
Then you can find all Persons with first or last name or whose parent with last name
然后你可以找到所有有名字或姓氏的人或其父母姓氏
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
Not the best example for the use of this, but just trying to fit it with the question.
不是使用它的最佳示例,而只是试图将其与问题相适应。
回答by Zsolt
For me (Rails 4.2.5) it only works like this:
对我来说(Rails 4.2.5)它只能这样工作:
{ where("name = ? or name = ?", a, b) }
回答by Christian Fazzini
An updated version of Rails/ActiveRecord may support this syntax natively. It would look similar to:
Rails/ActiveRecord 的更新版本可能本身就支持这种语法。它看起来类似于:
Foo.where(foo: 'bar').or.where(bar: 'bar')
As noted in this pull request https://github.com/rails/rails/pull/9052
如本拉取请求中所述https://github.com/rails/rails/pull/9052
For now, simply sticking with the following works great:
就目前而言,只需坚持以下工作即可:
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
回答by dhulihan
This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeelinstead. It's made by the same author. Here's how'd you'd perform an OR based chain:
如果您使用的是 Rails 3.0+,这将是 MetaWhere 的一个很好的候选者,但它不适用于 Rails 3.1。您可能想尝试使用squeel。它是由同一作者制作的。以下是您如何执行基于 OR 的链:
Person.where{(name == "John") | (lastname == "Smith")}
You can mix and match AND/OR, among many other awesome things.
您可以混合和匹配 AND/OR 以及许多其他很棒的东西。

