2012-06-03 12 views
11

Quiero obtener todos los usuarios que tienen un correo electrónico como el que se proporciona o el nombre y apellido. Así, por ejemplo:Cómo utilizar la condición O en la consulta de ActiveRecord

users = User.where(:first_name => "James", :last_name => "Scott") 

que devolverá todos los usuarios que tienen el nombre y apellido de "James" & "de Scott".

users = User.where(:email => "[email protected]") 

que devolverá al usuario con el correo electrónico como "[email protected]".

¿Hay una manera de hacer una cláusula where para devolver cualquiera de los usuarios con el mismo nombre y apellido y el usuario con el correo electrónico que coincide en una where consulta o necesito hacer una fusión en el 2 por separado where cláusulas.

+1

posible duplicado de [ActiveRecord o una consulta] (http://stackoverflow.com/questions/3639656/activerecord-or-query) –

+1

@Trace: ha olvidado de seleccionar una respuesta o al menos darle un poco realimentación. – tokland

Respuesta

0

Puede usar condiciones de cadena, como en Client.where("orders_count = ? AND locked = ?", params[:orders], false), y usar OR junto con AND. Tenga cuidado con la prioridad de esos operadores sin embargo.

Cf Active Record Query Interface guide

11

Prueba esto:

users = User.where("(first_name = 'James' and last_name = 'Scott') or email = '[email protected]'") 

para interpolar variables:

users = User.where("(first_name = ? and last_name = ?) or email = ?", first_name, last_name, email) 
+10

¡Ahhhh inyección SQL en el segundo! –

+1

¡Está bien! Solo mostrándole sintaxis. Tú ganas. Déjame arreglarlo. – Anil

+1

Eso es mejor. E incluso si solo fuera un ejemplo, los agujeros de seguridad nunca deberían estar presentes ':)'. –

5

Si no desea escribir SQL como los otros han mencionado, se puede acceder a la arel estructuras directamente (parece que otra respuesta tiene eso) o usa la gema squeel para hacerlo de una manera mucho más elegante:

User.where{(first_name == 'Ernie') & (last_name == 'Scott') | (email == 'james#gmail.com')} 
+0

Creo que te refieres a '==' – tokland

+0

Sí, supongo que sería más como el rubí. En cualquier caso, necesitaría un ajuste para usar variables también. – DGM

7

Si prefiere un enfoque DSL (sin SQL), puede utilizar la capa subyacente Arel:

t = User.arel_table 
users = User.where(
    (t[:first_name].eq('Ernie').and(t[:last_name].eq('Scott')). 
    or(t[:email].eq('james#gmail.com')) 
) 

Eso es un poco feo, pero si se utiliza algún envoltorio sobre Arel (por ejemplo, this one), el código es mucho más agradable:

users = User.where(
    ((User[:first_name] == 'Ernie') & (User[:last_name] == 'Scott')) | 
    (User[:email] == 'james#gmail.com') 
) 
+1

Contenedor interesante, siempre me ha disgustado tener que usar arel, pero podría ser menos reacio a esto con esto; bonito. –

19

rieles 5 viene con un or method.

Este método acepta un objeto ActiveRecord::Relation. por ejemplo:

User.where(first_name: 'James', last_name: 'Scott') 
    .or(User.where(email: '[email protected]')) 
+1

Para la aplicación Rails 5, esta debería considerarse la respuesta más correcta. –

Cuestiones relacionadas