Trả lời

153

Khả năng chuỗi or khoản cùng với where điều khoản trong ActiveRecord truy vấn sẽ có mặt tại Rails 5. Xem related discussion and the pull request.

Vì vậy, bạn sẽ có thể làm những điều sau đây trong Rails 5:

Để có được một post với id 1 hoặc 2:

Post.where('id = 1').or(Post.where('id = 2')) 

Một số ví dụ khác:

(A & & B) || C:

Post.where(a).where(b).or(Post.where(c)) 

(Một || B) & & C:

Post.where(a).or(Post.where(b)).where(c) 
+3

Làm cách nào để nhận được (A || B) && (C || D). Tôi đã thử Post.where (a) .or (Post.where (b)). Nơi (c) .ho (Post.where (d)) nhưng Nó sản xuất như sau: (A || B) && C || D – Imran

+3

@Imran tôi tin rằng nó sẽ là 'Post.where (a) .or (Post.where (b)). Where (Post.where (c) .or (Post.where (d)))' điều này sẽ tạo ra (a || b) && (c || d) – engineersmnky

12

Chúng tôi không cần phải chờ đợi cho đường ray 5 để sử dụng truy vấn OR này. Chúng tôi cũng có thể sử dụng nó với rails 4.2.3. Có một backport here.

Cảm ơn Eric-Guo cho đá quý where-or, Bây giờ chúng tôi có thể thêm chức năng này OR trong >= rails 4.2.3 cũng sử dụng đá quý này.

3

tôi cần phải làm một (A && B) || (C && D) || (E && F)

Nhưng trong tình trạng hiện Rails 5.1.4 's này có được của quá phức tạp để hoàn thành với Arel hoặc chuỗi. Nhưng tôi vẫn muốn sử dụng Rails để tạo càng nhiều truy vấn càng tốt.

Vì vậy, tôi đã thực hiện một hack nhỏ:

Trong mô hình của tôi, tôi đã tạo ra một tin phương pháp gọi là sql_where:

private 
    def self.sql_where(*args) 
    sql = self.unscoped.where(*args).to_sql 
    match = sql.match(/WHERE\s(.*)$/) 
    "(#{match[1]})" 
    end 

Tiếp theo trong phạm vi của tôi, tôi đã tạo ra một mảng để chứa của HOẶC

scope :whatever, -> { 
    ors = [] 

    ors << sql_where(A, B) 
    ors << sql_where(C, D) 
    ors << sql_where(E, F) 

    # Now just combine the stumps: 
    where(ors.join(' OR ')) 
} 

Điều này sẽ tạo ra kết quả truy vấn mong đợi: SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F)).

Và bây giờ tôi có thể dễ dàng kết hợp điều này với các phạm vi khác, v.v. mà không có bất kỳ sai OR nào.

Vẻ đẹp là sql_where của tôi lấy đối số bình thường ở mệnh đề: sql_where(name: 'John', role: 'admin') sẽ tạo ra (name = 'John' AND role = 'admin').

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