Làm thế nào để bạn thực hiện một or
truy vấn trong Rails 5 ActiveRecord? Ngoài ra, có thể liên kết or
với where
các truy vấn ActiveRecord không?
Làm thế nào để bạn thực hiện một or
truy vấn trong Rails 5 ActiveRecord? Ngoài ra, có thể liên kết or
với where
các truy vấn ActiveRecord không?
Câu trả lời:
Khả năng xâu chuỗi or
mệnh đề cùng với where
mệnh đề trong ActiveRecord
truy vấn sẽ có sẵn trong Rails 5 . Xem thảo luận liên quan và yêu cầu kéo .
Vì vậy, bạn sẽ có thể thực hiện những việc sau 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))
(A || B) && C:
Post.where(a).or(Post.where(b)).where(c)
Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))
cái này nên tạo (a || b) && (c || d)
ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Tôi cần phải làm một (A && B) || (C && D) || (E && F)
Nhưng ở 5.1.4
trạng thái hiện tại của Rails , điều này quá phức tạp để thực hiện 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 mình, tôi đã tạo một phương thức riêng được 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 một mảng để giữ OR
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 '))
}
Mà 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ỳ HOẶC sai trái nào.
Vẻ đẹp là sql_where của tôi nhận các đối số mệnh đề where-bình thường:
sql_where(name: 'John', role: 'admin')
sẽ tạo ra (name = 'John' AND role = 'admin')
.
.merge
tương đương với && và xây dựng một cái cây thích hợp để chụp các parens của bạn. Một cái gì đó giống như ... (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
, giả sử mỗi người trong số các phạm vi ngoại hình giống nhưModel.where(...)
Rails 5 có khả năng cho or
mệnh đề với where
. Ví dụ.
User.where(name: "abc").or(User.where(name: "abcd"))