I know there are 3 main notations for supplying arguments to the where
ActiveRecord method:
Specifying and
for the where
method is straight forward:
# Pure String notation
Person.where("name = 'Neil' AND age = 27")
# Array notation
Person.where(["name = ? AND age = ?", 'Neil', 27])
# Hash notation
Person.where({name: "Neil", age: 27})
Specifying or
for this same where
method is stumping me for the hash syntax. Is it possible?
# Pure String notation
Person.where("name = 'Neil' OR age = 27")
# Array notation
Person.where(["name = ? OR age = ?", 'Neil', 27])
# Hash notation DOESN'T WORK
Person.where({name: "Neil" OR age: 27})
There are 5 options that could be considered as implementations of «Hash notation» (the last two are kinda hash-ish):
With Ruby on Rails 5 you are able to do the following chaining using ActiveRecord::Relation#or
method:
Person.where(name: 'Neil').or(Person.where(age: 27))
Use where_values
together with reduce
. The unscoped
method is necessary only for Rails 4.1+ to ensure default_scope
is not included in the where_values
. Otherwise predicates from both default_scope
and where
would be chained with the or
operator:
Person.where(
Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or)
)
Install third-party plugins that implement these or similar features, for example:
Where Or (backport of the Ruby on Rails 5 .or
feature mentioned above)
Person.where{(name == 'Neil') | (age == 27)}
Person.where(name: 'Neil').or(age: 27)
Person.where.anyof(name: 'Neil', age: 27)
Person.where(
(SmartTuple.new(' or ') << {name: 'Neil', age: 27}).compile
)
Use Arel:
Person.where(
Person.arel_table[:name].eq('Neil').or(
Person.arel_table[:age].eq(27)
)
)
Use prepared statements with named parameters:
Person.where('name = :name or age = :age', name: 'Neil', age: 27)