Rails 5 ActiveRecord'da nasıl orsorgu yaparsınız ? Ayrıca ActiveRecord sorgularında zincirleme yapmak mümkün müdür ?orwhere
Rails 5 ActiveRecord'da nasıl orsorgu yaparsınız ? Ayrıca ActiveRecord sorgularında zincirleme yapmak mümkün müdür ?orwhere
Yanıtlar:
Sorgudaki ormadde ile birlikte whereyan tümceyi zincirleme yeteneği ActiveRecord, Rails 5'te mevcut olacaktır . Bkz ilgili tartışma ve çekme isteğini .
Böylece, Rails 5'te aşağıdakileri yapabileceksiniz :
1 veya 2 postile bir almak için id:
Post.where('id = 1').or(Post.where('id = 2'))
Diğer bazı örnekler:
(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)))yaratması gerektiğine inanıyorum (a || b) && (c || d)
ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Bu ORsorguyu kullanmak için rayların 5 beklemesine gerek yok . İle de kullanabiliriz rails 4.2.3. Burada bir arka port var .
Eric-Guo'ya mücevher için teşekkürler - veya , Şimdi bu ORişlevi >= rails 4.2.3bu mücevheri kullanarak da ekleyebiliriz .
Yapmam gerek (A && B) || (C && D) || (E && F)
Ancak Rails'in 5.1.4şu anki durumunda bu, Arel veya zincir ile başarılamayacak kadar karmaşık. Ancak yine de mümkün olduğunca fazla sorgu oluşturmak için Rails'i kullanmak istedim.
Bu yüzden küçük bir hack yaptım:
Modelimde özel bir yöntem oluşturdum sql_where:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
Ardından, kapsamımda ameliyathaneleri tutmak için
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 '))
}
Hangi beklenen sorgu sonucu üretecektir:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F)).
Ve şimdi bunu herhangi bir yanlış OR'ler olmadan diğer kapsamlarla vb. Kolayca birleştirebilirim.
Sql_where'in normal where-clause argümanlarını alması güzelliği:
sql_where(name: 'John', role: 'admin')üretecek (name = 'John' AND role = 'admin').
.merge&& eşdeğeri olarak kullanabilir ve parenslerinizi yakalamak için uygun bir ağaç inşa edebilirsiniz. (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))Her bir kapsamın şuna benzediğini varsayarsak ... gibi bir şeyModel.where(...)
Rails 5, orile madde kullanma yeteneğine sahiptir where. Örneğin.
User.where(name: "abc").or(User.where(name: "abcd"))