ActiveRecord O consulta

¿Cómo se hace una consulta O en Rails 3 ActiveRecord. Todos los ejemplos que encuentro solo tienen consultas AND.

Editar: El método O está disponible desde Rails 5. Ver ActiveRecord :: QueryMethods

Usa ARel

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

Si desea utilizar un operador OR en el valor de una columna, puede pasar una matriz a .where y ActiveRecord usará IN(value,other_value) :

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

productos:

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

Esto debería lograr el equivalente de un OR en una sola columna

en Rails 3, debería ser

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

Esto también incluye sql sin procesar, pero no creo que haya una forma en ActiveRecord de hacer operaciones OR. Tu pregunta no es una pregunta novato.

Una versión actualizada de Rails / ActiveRecord puede admitir esta syntax de forma nativa. Se vería similar a:

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

Como se señala en esta solicitud de extracción https://github.com/rails/rails/pull/9052

Por ahora, simplemente seguir con lo siguiente funciona muy bien:

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

Actualización: según https://github.com/rails/rails/pull/16052 la función or estará disponible en Rails 5

Actualización: la característica se ha fusionado con la twig Rails 5

Rails ha agregado recientemente esto a ActiveRecord. Parece que se lanzará en Rails 5. Compromiso de dominar 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) 

Si desea utilizar matrices como argumentos, el siguiente código funciona en 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)) 

Más información: consultas OR con matrices como argumentos en Rails 4 .

Rails 5 viene con un or método. (l tinta a la documentación )

Este método acepta un objeto ActiveRecord::Relation . p.ej:

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

El complemento de MetaWhere es completamente sorprendente.

Mezcla fácilmente OR’s y AND’s, une condiciones en cualquier asociación e incluso especifica OUTER JOIN’s.

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

Solo agregue un quirófano en las condiciones

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

Acabo de extraer este complemento del trabajo del cliente que le permite combinar ámbitos con .or. , ex. Post.published.or.authored_by(current_user) . Squeel (implementación más reciente de MetaSearch) también es excelente, pero no te permite O scopes, por lo que la lógica de consulta puede ser un poco redundante.

Podrías hacerlo como:

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

o más elegante, instala rails_or gem y hazlo como:

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

Con rails + arel, una forma 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 
 Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')