2012-06-03 35 views
11

Tôi muốn lấy tất cả người dùng có email như địa chỉ được cung cấp hoặc họ và tên. Ví dụ:Cách sử dụng điều kiện OR trong truy vấn ActiveRecord

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

sẽ trả về tất cả người dùng có họ và tên "James" & "Scott".

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

sẽ trả lại người dùng bằng email là "[email protected]".

Có cách nào để thực hiện mệnh đề where để trả lại người dùng có cùng tên và họ và người dùng có email khớp với một truy vấn where hoặc tôi cần hợp nhất trên 2 riêng biệt where điều khoản.

+1

thể trùng lặp của [ActiveRecord OR truy vấn] (http://stackoverflow.com/questions/3639656/activerecord-or-query) –

+1

@Trace: bạn quên chọn một câu trả lời hoặc ít nhất đưa ra một số Phản hồi. – tokland

Trả lời

0

Bạn có thể sử dụng điều kiện chuỗi, như trong Client.where("orders_count = ? AND locked = ?", params[:orders], false) và sử dụng OR kết hợp với AND. Hãy cẩn thận với sự ưu tiên của những nhà khai thác mặc dù.

Cf Active Record Query Interface guide

11

Hãy thử điều này:

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

Để suy biến:

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

Ahhhh SQL injection trong lần thứ hai! –

+1

Được rồi! Chỉ hiển thị cú pháp của anh ấy. Bạn thắng. Để tôi sửa nó. – Anil

+1

Tốt hơn. Và ngay cả khi nó chỉ là một ví dụ về các lỗ hổng bảo mật thì không bao giờ có mặt ':)'. –

5

Nếu bạn không muốn viết SQL như những người khác đã đề cập, bạn có thể truy cập arel cấu trúc trực tiếp (trông giống như một câu trả lời có đó) hoặc sử dụng đá quý squeel để làm điều đó nhiều hơn nữa thanh lịch:

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

Tôi nghĩ rằng bạn có nghĩa là '==' – tokland

+0

vâng tôi đoán rằng sẽ giống như ruby. Trong mọi trường hợp, nó sẽ cần một tinh chỉnh để sử dụng các biến là tốt. – DGM

7

Nếu bạn thích một cách tiếp cận DSL (không có SQL), có thể sử dụng cơ bản lớp 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')) 
) 

Đó là một chút xấu xí, nhưng nếu bạn sử dụng một số wrapper trên Arel (ví dụ, this one), mã rất đẹp:

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

Thú vị wrapper, tôi đã luôn luôn không thích phải sử dụng arel, nhưng tôi có thể ít nghịch với nó với điều này; tốt đẹp. –

19

Rails 5 đi kèm với một or method.

Phương thức này chấp nhận đối tượng ActiveRecord::Relation. ví dụ:

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

Đối với ứng dụng Rails 5, điều này nên được xem là câu trả lời đúng nhất. –

Các vấn đề liên quan