¿Cómo se hace una consulta OR en Rails 3 ActiveRecord. Todos los ejemplos que encuentro solo tienen consultas AND.ActiveRecord O consulta
Editar: O método está disponible desde los carriles 5. Ver ActiveRecord::QueryMethods
¿Cómo se hace una consulta OR en Rails 3 ActiveRecord. Todos los ejemplos que encuentro solo tienen consultas AND.ActiveRecord O consulta
Editar: O método está disponible desde los carriles 5. Ver ActiveRecord::QueryMethods
Uso ARel
t = Post.arel_table
results = Post.where(
t[:author].eq("Someone").
or(t[:title].matches("%something%"))
)
El resultado ting 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%'))
Se siente un poco desordenado, pero al menos no estoy escribiendo sql, ¡lo cual no es correcto! Tendré que estudiar el uso de Arel más. – pho3nixf1re
Lo bueno es que no tiene que hacerlo todo de una vez, puede generar consultas y no llegará a la base de datos hasta que realmente necesite los datos. Este ejemplo se combinó solo por brevedad. –
No puedo dejar de ver cuánto más elegante es Sequel – Macario
simplemente añada una o en las condiciones
Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
Esta es más la sintaxis de Rails 2, y me obliga a escribir al menos parte de una cadena sql. – pho3nixf1re
El plugin MetaWhere es completamente sorprendente.
¡Mezcle fácilmente los OR's y AND's, únase a las condiciones de cualquier asociación e incluso especifique OUTER JOIN's!
en Rails 3, debe 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. Tu pregunta no es una pregunta novato.
Incluso si hay sql en bruto, esta afirmación parece mucho más clara para mí que Arel. Quizás incluso DRYer. – jibiel
si necesita encadenar, otras combinaciones de tablas que pueden tener las columnas con los mismos nombres de columna, debe usarlo así, 'Page.where (" pages.column =? Or pages.other_column =? ", Value, other_value) ' – rubyprince
Y eso falla si la consulta alias las tablas. Es entonces cuando arel brilla. – DGM
Acabo de extraer this plugin del trabajo del cliente que le permite combinar ámbitos con .or.
, ej. Post.published.or.authored_by(current_user)
. Squeel (implementación más reciente de MetaSearch) también es excelente, pero no te permite O alcances, por lo que la lógica de consulta puede ser un poco redundante.
Si desea utilizar un operador o sobre 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 debería lograr el equivalente de OR
en una sola columna
esta es la respuesta más limpia de "carriles", debería haber sido aceptada – koonse
Gracias @koonse, no es * exactamente * una consulta 'O', pero produce el mismo resultado para esta situación. – deadkarma
Ayuda si puede - http://stackoverflow.com/questions/15517286/transformation-of-query-to-active-record –
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: OR queries with arrays as arguments in Rails 4.
O esto: 'Order.where (query.where_values.inject (: o))' para usar arel hasta el final. –
> O consultas con matrices como argumentos en Rails 4. ¡Enlace útil! ¡Gracias! –
Esto es asombroso. – rubyprince
Una versión actualizada de Rails/ActiveRecord puede admitir esta sintaxis de forma 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 el siguiente funciona muy bien:
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
Actualización: Según https://github.com/rails/rails/pull/16052 la or
característica estará disponible en Rails 5
Actualización: característica se ha fusionado a Rails 5 rama
'o' está disponible ahora Rails 5 pero no implementado de esta manera porque espera que se pase 1 argumento. Espera un objeto Arel. Ver la respuesta aceptada –
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
Carriles ha añadido recientemente esto en ActiveRecord. Parece que sea lanzado en los carriles 5. Comprometidos con la ya dominar:
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)
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')
Agregue algunas explicaciones a su respuesta – kvorobiev
Creo que Matthew se estaba refiriendo a la gema [activerecord_any_of] (https://github.com/oelmekki/activerecord_any_of) que agrega compatibilidad con esta sintaxis. – DannyB
Si es cierto, gracias @DannyB. La respuesta debe explicar su contexto. – Sebastialonso
rieles 5 viene con un método or
. (l ink to documentation)
Este método acepta un objeto ActiveRecord::Relation
. por ejemplo:
User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
Se podí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)
Aprende SQL. ActiveRecord hace que sea más fácil hacer que las cosas funcionen, pero aún necesita saber qué están haciendo sus consultas, de lo contrario, es posible que su proyecto no se escale. También pensé que podría salir adelante sin tener que lidiar con SQL, y estaba muy equivocado al respecto. – ryan0
@ ryan0, tienes razón. Podemos usar gemas extravagantes y otras cosas, pero debemos ser conscientes de lo que estas gemas están haciendo dentro y cuál es la tecnología subyacente, y quizás usar las tecnologías subyacentes sin la ayuda de la gema, si es necesario, por el bien de actuación. Las gemas se crean con un número específico de usos en mente, pero puede haber situaciones en las que uno de los casos de uso en nuestro proyecto podría ser diferente. – rubyprince
Puede ser de ayuda: [ActiveRecord O consulte la notación hash] (http://stackoverflow.com/q/31096009/3444240) – potashin