Запрос ActiveRecord OR

Как вы выполняете запрос OR в Rails 3 ActiveRecord. Все примеры, которые я нахожу, имеют только И-запросы.

Изменить: метод OR доступен с Rails 5. См. Раздел ActiveRecord :: QueryMethods

Использовать AREL

 t = Post.arel_table results = Post.where( t[:author].eq("Someone"). or(t[:title].matches("%something%")) ) - t = Post.arel_table results = Post.where( t[:author].eq("Someone"). or(t[:title].matches("%something%")) ) - t = Post.arel_table results = Post.where( t[:author].eq("Someone"). or(t[:title].matches("%something%")) ) 

Полученный SQL:

 ree-1.8.7-2010.02 > puts Post.where(t[:author].eq("Someone").or(t[:title].matches("%something%"))).to_sql SELECT "posts".* FROM "posts" WHERE (("posts"."author" = 'Someone' OR "posts"."title" LIKE '%something%')) 

Если вы хотите использовать оператор OR по значению одного столбца, вы можете передать массив в .where а ActiveRecord будет использовать IN(value,other_value) :

Model.where(:column => ["value", "other_value"]

выходы:

 SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value') 

Это должно обеспечить эквивалент OR в одном столбце

в Rails 3 это должно быть

 Model.where("column = ? or other_column = ?", value, other_value) 

Это также включает raw sql, но я не думаю, что в ActiveRecord есть способ сделать операцию OR. Ваш вопрос не вопрос.

Обновленная версия Rails / ActiveRecord может поддерживать этот синтаксис изначально. Он будет выглядеть так:

 Foo.where(foo: 'bar').or.where(bar: 'bar') 

Как отмечено в этом запросе на извлечение https://github.com/rails/rails/pull/9052

Пока что просто придерживаться следующих работ отлично:

 Foo.where('foo= ? OR bar= ?', 'bar', 'bar') 

Обновление: согласно https://github.com/rails/rails/pull/16052, эта функция будет доступна в Rails 5

Обновление: функция была объединена с ветвью Rails 5

Rails недавно добавила это в ActiveRecord. Он выглядит выпущенным в Rails 5. Он уже успел освоить:

https://github.com/rails/rails/commit/9e42cf019f2417473e7dcbfcb885709fa2709f89

 Post.where(column: 'something').or(Post.where(other: 'else')) # => SELECT * FROM posts WHERE (column = 'something') OR (other = 'else) 

Если вы хотите использовать массивы в качестве аргументов, в Rails 4 работает следующий код:

 query = Order.where(uuid: uuids, id: ids) Order.where(query.where_values.map(&:to_sql).join(" OR ")) #=> Order Load (0.7ms) SELECT "orders".* FROM "orders" WHERE ("orders"."uuid" IN ('5459eed8350e1b472bfee48375034103', '21313213jkads', '43ujrefdk2384us') OR "orders"."id" IN (2, 3, 4)) 

Дополнительная информация: ИЛИ запросы с массивами в качестве аргументов в Rails 4 .

Rails 5 поставляется с методом or . (l чернила в документации )

Этот метод принимает объект ActiveRecord::Relation . например:

 User.where(first_name: 'James').or(User.where(last_name: 'Scott')) 

Плагин MetaWhere полностью потрясающий.

Легко смешивайте OR и AND, присоединяйте условия к любой ассоциации и даже укажите OUTER JOIN!

 Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer} 

Просто добавьте OR в условия

 Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value]) 

Я просто извлек этот плагин из работы клиента, который позволяет объединять области с .or. , например. Post.published.or.authored_by(current_user) . Squeel (более новая реализация MetaSearch) также отличная, но не позволяет вам областям OR, поэтому логика запросов может быть немного избыточной.

Вы можете сделать это так:

 Person.where("name = ? OR age = ?", 'Pearl', 24) 

или более элегантный, установите rails_or gem и сделайте это как:

 Person.where(:name => 'Pearl').or(:age => 24) 

С рельсами + isl, более понятным способом:

 # Table name: messages # # sender_id: integer # recipient_id: integer # content: text class Message < ActiveRecord::Base scope :by_participant, ->(user_id) do left = arel_table[:sender_id].eq(user_id) right = arel_table[:recipient_id].eq(user_id) where(Arel::Nodes::Or.new(left, right)) end end 

Производит:

 $ Message.by_participant(User.first.id).to_sql => SELECT `messages`.* FROM `messages` WHERE `messages`.`sender_id` = 1 OR `messages`.`recipient_id` = 1 
 Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway') 
Давайте будем гением компьютера.