Запрос ActiveRecord OR

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

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

Ответ 1

Используйте ARel

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%'))

Ответ 2

Если вы хотите использовать оператор 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 для одного столбца

Ответ 3

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

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

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

Ответ 4

Обновленная версия 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 функция or будет доступна в Rails 5

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

Ответ 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)

Ответ 6

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

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

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

Ответ 7

Если вы хотите использовать массивы в качестве аргументов, в 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.

Ответ 8

Плагин 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}

Ответ 9

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

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

Ответ 10

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

Ответ 11

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

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

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

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

Ответ 12

С рельсами + 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

Ответ 13

Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')