ActiveRecord o una consulta
-
30-09-2019 - |
Pregunta
¿Cómo se hace un OR consulta en los carriles 3 ActiveRecord. Todos los ejemplos que encontrar apenas tienen y consultas.
Edit: o método está disponible desde los carriles 5. Véase ActiveRecord :: QueryMethods
Solución
t = Post.arel_table
results = Post.where(
t[:author].eq("Someone").
or(t[:title].matches("%something%"))
)
El SQL resultante:
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%'))
Otros consejos
Si desea utilizar un operador OR en el valor de una columna, puede pasar una matriz a .where
y ActiveRecord utilizará IN(value,other_value)
:
Model.where(:column => ["value", "other_value"]
salidas:
SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value')
Esto debe alcanzar el equivalente de un OR
en una sola columna
en los carriles 3, debería ser
Model.where("column = ? or other_column = ?", value, other_value)
Esto también incluye SQL en bruto, pero no creo que hay una manera de hacer ActiveRecord operación OR. Su pregunta no es una cuestión novato.
Una versión actualizada de rieles / ActiveRecord puede apoyar esta sintaxis nativa. Se vería similar a:
Foo.where(foo: 'bar').or.where(bar: 'bar')
Como se ha señalado en esta solicitud de extracción https://github.com/rails/rails/pull/ 9052
Por ahora, sólo tiene que pegarse con la siguiente funciona muy bien:
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
Actualización: https://github.com/rails / carriles / tirón / 16052 la característica or
estará disponible en los carriles 5
Actualización: Feature se ha fusionado a 5 rieles rama
Rieles ha añadido recientemente esto en ActiveRecord. Parece que sea lanzado en los carriles 5. Comprometidos con la maestra ya:
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)
Carriles 5 viene con un método or
. (L tinta a la documentación )
Este método acepta un objeto ActiveRecord::Relation
. por ejemplo:
User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
Si desea utilizar matrices como argumentos, el siguiente código funciona en los carriles 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))
Más información:. o consultas con arrays como argumentos en los carriles 4
El MetaWhere plugin es totalmente increíble.
Fácil de mezclar o de Y y de las condiciones, se unen en cualquier forma de asociación, e incluso especifican EXTERIOR de unirse!
Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}
Sólo tiene que añadir una o en las condiciones
Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
Me acaba de extraer este plugin desde el cliente de trabajo que le permite combinar con alcances .or.
, ex. Post.published.or.authored_by(current_user)
. Squeel (nueva aplicación de MetaSearch) también es grande, pero no te deja entrar o ámbitos, por lo que la lógica de consulta puede conseguir un poco redundante.
Con rieles + Arel, de una manera más clara:
# 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
Produce:
$ Message.by_participant(User.first.id).to_sql
=> SELECT `messages`.*
FROM `messages`
WHERE `messages`.`sender_id` = 1
OR `messages`.`recipient_id` = 1
podría hacerlo como:
Person.where("name = ? OR age = ?", 'Pearl', 24)
o más elegante, instalar rails_or joya y hacerlo como:
Person.where(:name => 'Pearl').or(:age => 24)
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')