Jak wykonać or
zapytanie w Rails 5 ActiveRecord? Czy można też łączyć w łańcuch or
z where
zapytaniami ActiveRecord?
Jak wykonać or
zapytanie w Rails 5 ActiveRecord? Czy można też łączyć w łańcuch or
z where
zapytaniami ActiveRecord?
Odpowiedzi:
Możliwość łączenia w łańcuch or
klauzuli wraz z where
klauzulą w ActiveRecord
zapytaniu będzie dostępna w Railsach 5 . Zobacz powiązaną dyskusję i żądanie ściągnięcia .
W Rails 5 będziesz mógł więc wykonać następujące czynności :
Aby dostać post
się z id
1 lub 2
Post.where('id = 1').or(Post.where('id = 2'))
Kilka innych przykładów:
(A && B) || DO:
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)))
powinno to stworzyć (a || b) && (c || d)
ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Nie musimy czekać, aż rails 5 użyje tego OR
zapytania. Możemy go również używać z rails 4.2.3
. Jest backport tutaj .
Dziękuję Ericowi-Guo za klejnot, gdzie-lub , teraz możemy dodać tę OR
funkcjonalność >= rails 4.2.3
również za pomocą tego klejnotu.
Musiałem zrobić (A && B) || (C && D) || (E && F)
Ale w 5.1.4
obecnym stanie Railsów jest to zbyt skomplikowane, aby wykonać to z Arelem lub łańcuchem. Ale nadal chciałem używać Railsów do generowania jak największej liczby zapytań.
Więc zrobiłem mały hack:
W swoim modelu stworzyłem prywatną metodę o nazwie sql_where
:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
Następnie w moim zakresie utworzyłem tablicę do przechowywania 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 '))
}
Który przyniesie oczekiwanego rezultatu zapytania:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.
A teraz mogę łatwo połączyć to z innymi celownikami itp. Bez niewłaściwych sal operacyjnych.
Piękno polega na tym, że mój sql_where przyjmuje normalne argumenty where-clause:
sql_where(name: 'John', role: 'admin')
wygeneruje (name = 'John' AND role = 'admin')
.
.merge
jako odpowiednika && i zbudować odpowiednie drzewo, aby uchwycić swoje pareny. Coś jak ... (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
zakładając, że każdy z teleskopów wygląda Model.where(...)
Rails 5 ma możliwość or
klauzuli z where
. Na przykład.
User.where(name: "abc").or(User.where(name: "abcd"))