2012-06-03 9 views
11

Chcę pobrać wszystkich użytkowników, którzy mają wiadomość e-mail jako dostarczoną lub imię i nazwisko. Tak więc na przykład:Sposób korzystania z warunku OR w kwerendzie ActiveRecord

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

który powróci wszystkich użytkowników, którzy mają imię i nazwisko „James” & „Scott”.

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

, która zwróci użytkownika z wiadomością e-mail jako "[email protected]".

Czy istnieje sposób, aby zrobić where klauzulę powrotu albo użytkownikom tego samego imienia i nazwiska, a użytkownik z wiadomości e-mail, który pasuje w jednym where zapytaniem, czy trzeba zrobić scalania na 2 oddzielne where klauzule.

+1

możliwe duplikat [ActiveRecord lub zapytania] (http://stackoverflow.com/questions/3639656/activerecord-or-query) –

+1

@Trace: zapomniałeś zaznaczyć odpowiedź lub przynajmniej dać jakiś informacje zwrotne. – tokland

Odpowiedz

0

Można użyć warunków ciągów, jak w Client.where("orders_count = ? AND locked = ?", params[:orders], false), i użyć OR w połączeniu z AND. Bądź jednak ostrożny z priorytetem tych operatorów.

Por Active Record Query Interface guide

11

Spróbuj tego:

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

interpolować zmiennych:

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

Ahhhh SQL injection w drugim! –

+1

Dobra! Po prostu pokazuje mu składnię. Wygrałeś. Pozwól mi to naprawić. – Anil

+1

To lepiej. I nawet jeśli jest to tylko przykład, dziury w bezpieczeństwie nigdy nie powinny być obecne ':)'. –

5

Jeśli nie chcesz pisać SQL jak wspominają inni, można uzyskać dostęp do Struktury arel bezpośrednio (wygląda jak inna odpowiedź) lub użyj klejnotu squeel, aby zrobić to znacznie bardziej elegancko:

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

Myślę, że masz na myśli '==' – tokland

+0

tak, myślę, że byłoby bardziej jak rubin. W każdym razie potrzebowałoby to również zmiany parametrów. – DGM

7

Jeśli wolisz podejście DSL (bez SQL), mogą korzystać z leżącą u podstaw AREL warstwy:

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

to trochę brzydki, ale jeśli używasz jakiś wrapper nad AREL (np this one), kod jest dużo ładniejszy:

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

Interesujące opakowanie, zawsze nie lubiłem korzystać z Arel, ale może być mniej niechętny do tego; miły. –

19

Szyny 5 pochodzi z or method.

Ta metoda akceptuje obiekt ActiveRecord::Relation. np:

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

W przypadku aplikacji Rails 5 należy to uznać za najbardziej poprawną odpowiedź. –

Powiązane problemy