Wie führt man eine or
-Abfrage in Rails 5 ActiveRecord durch? Kann or
auch mit where
in ActiveRecord-Abfragen verkettet werden?
Die Möglichkeit, or
-Klausel zusammen mit where
-Klausel in ActiveRecord
-Abfrage zu verketten, ist in Rails 5 verfügbar. Siehe verwandte Diskussion und Pull-Anforderung .
In Rails 5 können Sie also Folgendes tun:
So erhalten Sie eine post
mit id
1 oder 2:
Post.where('id = 1').or(Post.where('id = 2'))
Einige andere Beispiele:
(A && B) || C:
Post.where(a).where(b).or(Post.where(c))
(A || B) && C:
Post.where(a).or(Post.where(b)).where(c)
Ich musste einen(A && B) || (C && D) || (E && F)
machen
Im aktuellen Stand von Rails 5.1.4
ist dies jedoch zu kompliziert, um es mit der Arel-Kette zu erreichen ..__ Ich wollte trotzdem Rails verwenden, um so viel wie möglich von der Abfrage zu generieren.
Also habe ich einen kleinen Hack gemacht:
In meinem Modell habe ich eine private -Methode mit dem Namen sql_where
erstellt:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
Als Nächstes habe ich in meinem Bereich ein Array erstellt, in dem die ODERs enthalten sind
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 '))
}
Daraus ergibt sich das erwartete Abfrageergebnis: SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.
Und jetzt kann ich dies problemlos mit anderen Bereichen usw. kombinieren, ohne falsche ODERs.
Die Schönheit ist, dass meine sql_where normale Argumente für Where-Klauseln verwendet: sql_where(name: 'John', role: 'admin')
generiert (name = 'John' AND role = 'admin')
.
(Nur eine Ergänzung zur Antwort von M Rakibul Islam.)
Mit Hilfe von Scopes kann der Code (je nach den Augen) hübscher werden:
scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
Rails 5 kann or
-Klausel mit where
.
User.where(name: "abc").or(User.where(name: "abcd"))