use*_*715 131 activerecord ruby-on-rails ruby-on-rails-3 rails-activerecord
我正在使用Rails3,ActiveRecord
只是想知道如何用OR语句而不是AND来链接范围.
例如
Person.where(:name => "John").where(:lastname => "Smith")
Run Code Online (Sandbox Code Playgroud)
这通常会返回name ='John'和lastname ='Smith',但我想:
name ='John'或lastname ='Smith'
Pet*_*ros 100
你会的
Person.where('name=? OR lastname=?', 'John', 'Smith')
Run Code Online (Sandbox Code Playgroud)
现在,新的AR3语法没有任何其他OR支持(没有使用某些第三方gem).
Rya*_*eaf 51
根据这个拉取请求,Rails 5现在支持链接查询的以下语法:
Post.where(id: 1).or(Post.where(id: 2))
Run Code Online (Sandbox Code Playgroud)
Dan*_*vin 48
使用ARel
t = Person.arel_table
results = Person.where(
t[:name].eq("John").
or(t[:lastname].eq("Smith"))
)
Run Code Online (Sandbox Code Playgroud)
kis*_*ber 38
Rails4的更新
不需要第三方宝石
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) }
Run Code Online (Sandbox Code Playgroud)
老答案
不需要第三方宝石
Person.where(
Person.where(:name => "John").where(:lastname => "Smith")
.where_values.reduce(:or)
)
Run Code Online (Sandbox Code Playgroud)
dai*_*no3 36
只需发布相同列OR查询的Array语法,以帮助窥视.
Person.where(name: ["John", "Steve"])
Run Code Online (Sandbox Code Playgroud)
Sim*_*tsa 22
您还可以使用MetaWhere gem来将您的代码与SQL内容混淆:
Person.where((:name => "John") | (:lastname => "Smith"))
Run Code Online (Sandbox Code Playgroud)
cod*_*mev 22
如果有人正在寻找这个更新的答案,看起来有一个现有的拉取请求,以进入Rails:https://github.com/rails/rails/pull/9052.
感谢@ j-mcnally的ActiveRecord猴子补丁(https://gist.github.com/j-mcnally/250eaaceef234dd8971b),您可以执行以下操作:
Person.where(name: 'John').or.where(last_name: 'Smith').all
Run Code Online (Sandbox Code Playgroud)
更有价值的是能够将范围链接到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) }
Run Code Online (Sandbox Code Playgroud)
然后,您可以找到所有具有姓或姓的人或具有姓氏的父母
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
Run Code Online (Sandbox Code Playgroud)
这不是使用它的最佳示例,而只是尝试将其与问题相符.
Fre*_*ore 11
我现在正在 Rails 6 中工作,看来现在这是可能的。使用OP的查询:
# in the Person model:
scope :john, -> { where(name: "John") }
scope :smith, -> { where(lastname: "Smith") }
scope :john_or_smith, -> { john.or(self.smith) }
Run Code Online (Sandbox Code Playgroud)
小智 9
对我来说(Rails 4.2.5)它只能这样工作:
{ where("name = ? or name = ?", a, b) }
Run Code Online (Sandbox Code Playgroud)
如果您希望提供一个范围(而不是明确地处理整个数据集),那么您应该使用 Rails 5 执行以下操作:
scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }
Run Code Online (Sandbox Code Playgroud)
或者:
def self.john_or_smith
where(name: "John").or(where(lastname: "Smith"))
end
Run Code Online (Sandbox Code Playgroud)
如果您使用Rails 3.0+,这将是MetaWhere的一个很好的候选者,但它不适用于Rails 3.1.你可能想尝试一下口号.它是由同一作者制作的.以下是您如何执行基于OR的链:
Person.where{(name == "John") | (lastname == "Smith")}
Run Code Online (Sandbox Code Playgroud)
你可以混合和匹配AND/OR,以及许多其他很棒的东西.
Rails/ActiveRecord的更新版本可以本机支持此语法.它看起来类似于:
Foo.where(foo: 'bar').or.where(bar: 'bar')
Run Code Online (Sandbox Code Playgroud)
如此拉动请求中所述https://github.com/rails/rails/pull/9052
现在,只需坚持下面的工作:
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
Run Code Online (Sandbox Code Playgroud)
Rails 4 + Scope + Arel
class Creature < ActiveRecord::Base
scope :is_good_pet, -> {
where(
arel_table[:is_cat].eq(true)
.or(arel_table[:is_dog].eq(true))
.or(arel_table[:eats_children].eq(false))
)
}
end
Run Code Online (Sandbox Code Playgroud)
我尝试用.or链接命名的范围并且没有运气,但这适用于找到那些布尔值设置的任何东西.像生成SQL一样
SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))
Run Code Online (Sandbox Code Playgroud)
这是一种非常方便的方法,并且在 Rails 5 中运行良好:
Transaction
.where(transaction_type: ["Create", "Correspond"])
.or(
Transaction.where(
transaction_type: "Status",
field: "Status",
newvalue: ["resolved", "deleted"]
)
)
.or(
Transaction.where(transaction_type: "Set", field: "Queue")
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
98255 次 |
| 最近记录: |