Я знаю, что есть 3 основных обозначения для предоставления аргументов where
метода ActiveRecord:
- Чистая строка
- Массив
- Hash
Указание and
для метода where
выполняется прямо:
# 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})
Указание or
для этого же метода where
- это то, что я хочу использовать для хеш-синтаксиса. Возможно ли это?
# 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})
Ответ 1
Существует 5 вариантов, которые можно было бы рассматривать как реализации "Обозначения хэша" (последние два имеют вид хэш-иш):
-
С Ruby on Rails 5 вы можете выполнить следующую цепочку с помощью метода ActiveRecord::Relation#or
:
Person.where(name: 'Neil').or(Person.where(age: 27))
-
Используйте where_values
вместе с reduce
. unscoped
необходим только для Rails 4.1+ для обеспечения default_scope
не включен в where_values
. В противном случае предикаты из default_scope
и where
будут связаны цепью с оператором or
:
Person.where(
Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or)
)
-
Установите сторонние плагины, реализующие эти или подобные функции, например:
-
Где или (обратная сторона упомянутой выше функции Ruby on Rails 5 .or
)
-
Squeel
Person.where{(name == 'Neil') | (age == 27)}
-
RailsOr
Person.where(name: 'Neil').or(age: 27)
-
ActiverecordAnyOf
Person.where.anyof(name: 'Neil', age: 27)
-
SmartTuple
Person.where(
(SmartTuple.new(' or ') << {name: 'Neil', age: 27}).compile
)
-
Используйте Arel:
Person.where(
Person.arel_table[:name].eq('Neil').or(
Person.arel_table[:age].eq(27)
)
)
-
Используйте подготовленные инструкции с именованными параметрами:
Person.where('name = :name or age = :age', name: 'Neil', age: 27)
Ответ 2
Как говорит potashin, вы можете использовать другие сторонние плагины, которые реализуют эту функцию. Я долгое время использовал Squeel и отлично работает для этого и гораздо больше функций, таких как сложные подзапросы или объединения.
Этот запрос с использованием squeel:
@people= Person.where{(name == 'Neil') | (age = 27)}