Как вы выполняете запрос OR в Rails 3 ActiveRecord. Все примеры, которые я нахожу, имеют только запросы AND.
Изменить: ИЛИ доступен метод с Rails 5. См. ActiveRecord:: QueryMethods
Как вы выполняете запрос OR в Rails 3 ActiveRecord. Все примеры, которые я нахожу, имеют только запросы AND.
Изменить: ИЛИ доступен метод с Rails 5. См. ActiveRecord:: QueryMethods
Используйте 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%'))
Если вы хотите использовать оператор 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 функция or
будет доступна в 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 5 поставляется с методом or
. (l чернила в документации)
Этот метод принимает объект ActiveRecord::Relation
. например:
User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
Если вы хотите использовать массивы в качестве аргументов, в 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.
Плагин 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')