ActiveRecord O consulta


Cómo hacer una consulta OR en Rails 3 ActiveRecord. Todos los ejemplos que encuentro solo tienen y consultas.

Editar: O el método está disponible desde Rails 5. Ver ActiveRecord:: Métodos de consulta

Author: user2262149, 2010-09-04

13 answers

Use 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%'))
 103
Author: Dan McNevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-03 22:08:35

Si desea usar 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"]

Salidas:

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

Esto debería lograr el equivalente de un {[4] } en una sola columna

 190
Author: deadkarma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-01 16:05:10

En Rails 3, debe 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 U operar. Tu pregunta no es una pregunta novata.

 140
Author: rubyprince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-15 07:19:18

Una versión actualizada de Rails/ActiveRecord puede soportar esta sintaxis de forma nativa. Sería similar a:

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

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

Por ahora, simplemente seguir con las siguientes obras grandes:

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 función se ha fusionado con Rails 5 branch

 47
Author: Christian Fazzini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-20 05:55:37

Rails ha añadido recientemente esto a ActiveRecord. Parece ser lanzado en Rails 5. Comprometido con el maestro 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)
 31
Author: Greg Olsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-18 10:44:22

Rails 5 viene con un método or. (ltinta para la documentación )

Este método acepta un objeto ActiveRecord::Relation. eg:

User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
 15
Author: Santhosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-19 09:04:51

Si desea utilizar arrays 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: O consultas con arrays como argumentos en Rails 4.

 14
Author: Rafał Cieślak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-08 18:03:18

El plugin MetaWhere es completamente asombroso.

Mezclar fácilmente OR y AND, unir condiciones en cualquier asociación, e incluso especificar OUTER JOIN's!

Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}
 7
Author: Duke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-15 05:50:54

Simplemente agregue un OR en las condiciones

Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
 6
Author: Toby Hede,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-03 22:05:29

Acabo de extraer este plugin del trabajo del cliente que te permite combinar ámbitos con .or., por ejemplo. Post.published.or.authored_by(current_user). Squeel (nueva implementación de Metabúsqueda) también es genial, pero no le permite A usted O a los ámbitos, por lo que la lógica de consulta puede ser un poco redundante.

 3
Author: Woahdae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-25 20:41:32

Podrías hacerlo así:

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

O más elegante, instale la gema rails_or y hágalo como:

Person.where(:name => 'Pearl').or(:age => 24)
 3
Author: khiav reoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-02 05:15:27

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
 1
Author: itsnikolay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-14 08:58:57
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')
 -3
Author: Matthew Rigdon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-08 18:25:46