2012-06-03 30 views
11

Voglio afferrare tutti gli utenti che hanno una e-mail come quella fornita o il nome e il cognome. Così, per esempio:Come utilizzare la condizione OR nella query ActiveRecord

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

che restituirà tutti gli utenti che hanno il nome e il cognome di "James" & "Scott".

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

che restituirà all'utente l'e-mail come "[email protected]".

C'è un modo per fare una clausola where di restituire entrambi gli utenti con lo stesso nome e cognome e l'utente con l'email che corrisponde in una where query o ho bisogno di fare un'unione sul 2 separata where clausole.

+1

possibile duplicato del [ActiveRecord OR interrogazione] (http://stackoverflow.com/questions/3639656/activerecord-or-query) –

+1

@Trace: ti sei dimenticato di selezionare una risposta, o almeno dare qualche risposta. – tokland

risposta

0

È possibile utilizzare condizioni di stringa come in Client.where("orders_count = ? AND locked = ?", params[:orders], false) e utilizzare OR in combinazione con AND. Attenzione però alla priorità di quegli operatori.

Cf Active Record Query Interface guide

11

Prova questo:

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

interpolare variabili:

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

Ahhhh Iniezione SQL nel secondo! –

+1

OK! Mostrandogli solo la sintassi. Hai vinto. Lascia che lo aggiusti. – Anil

+1

È meglio. E anche se è solo un esempio, non dovrebbero mai essere presenti buchi di sicurezza ':)'. –

5

Se non si desidera scrivere SQL come gli altri hanno detto, è possibile accedere alla strutture arel direttamente (sembra che un'altra risposta abbia questa) o usare la gemma squeel per farlo in modo molto più elegante:

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

Penso tu voglia dire "==" – tokland

+0

sì, immagino che sarebbe più come rubino. In ogni caso, sarebbe necessario un ritocco per utilizzare anche le variabili. – DGM

7

Se si preferisce un approccio DSL (senza SQL), è possibile utilizzare lo strato di Arel sottostante:

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

Questo è un po 'brutto, ma se si utilizza qualche involucro sopra Arel (ad esempio, this one), il codice è molto più bello:

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

Interessante wrapper, non mi è sempre piaciuto usare arel, ma potrei essere meno avverso con questo; simpatico. –

19

Rails 5 viene fornito con un or method.

Questo metodo accetta un oggetto ActiveRecord::Relation. ad esempio:

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

Per l'applicazione Rails 5 questa dovrebbe essere considerata la risposta più corretta. –

Problemi correlati