Angenommen, ich habe die folgenden zwei Objekte:
first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation
last_name_relation = User.where(:last_name => 'Fünke') # ActiveRecord::Relation
Ist es möglich, die beiden Beziehungen zu kombinieren, um ein ActiveRecord::Relation
Objekt zu erzeugen, das beide Bedingungen enthält?
Hinweis: Mir ist bewusst, dass ich die Orte verketten kann, an denen dieses Verhalten auftritt. Was mich wirklich interessiert, ist der Fall, in dem ich zwei separate ActiveRecord::Relation
Objekte habe.
ruby-on-rails
rails-activerecord
arel
Patrick Klingemann
quelle
quelle
Antworten:
Wenn Sie mit
AND
(Schnittpunkt) kombinieren möchten , verwenden Siemerge
:Wenn Sie mit
OR
(union) kombinieren möchten , verwenden Sie † :or
† Nur in ActiveRecord 5+; Installieren Sie für 4.2 den Where- oder Backport.
quelle
ActiveRecord::Relation
Typ sein soll?merge
eine Kreuzung ist, keine Vereinigung.#or
Methode im Januar 2015 zu ActiveRecord :: Relation hinzugefügt und wird Teil von Rails 5.0 sein , das Ende 2015 ausgeliefert wird. Sie ermöglicht die Verwendung des Operators OR, um WHERE- oder HAVING-Klauseln zu kombinieren. Sie können HEAD vor der offiziellen Veröffentlichung auschecken, wenn Sie es benötigen. Siehe Merge Pull Request # 16052 @Arcolye @AndrewMarshall @ Aldo-xoen-GiambellucaBeziehungsobjekte können in Arrays konvertiert werden. Dies negiert die Möglichkeit, anschließend ActiveRecord-Methoden für sie verwenden zu können, dies war jedoch nicht erforderlich. Ich war das:
Ruby 1.9, Schienen 3.2
quelle
merge
funktioniert eigentlich nicht soOR
. Es ist einfach Kreuzung (AND
)Ich hatte Probleme mit diesem Problem, ActiveRecord :: Relation-Objekte zu einem zu kombinieren, und fand keine funktionierende Lösung für mich.
Anstatt nach der richtigen Methode zu suchen, um aus diesen beiden Mengen eine Vereinigung zu erstellen, konzentrierte ich mich auf die Algebra der Mengen. Sie können dies auf unterschiedliche Weise nach dem Gesetz von De Morgan tun
ActiveRecord bietet die Zusammenführungsmethode (AND) und Sie können auch not method oder none_of (NOT) verwenden.
Sie haben hier (A u B) '= A' ^ B '
UPDATE: Die obige Lösung eignet sich für komplexere Fälle. In Ihrem Fall wird so etwas ausreichen:
quelle
Ich habe dies auch in vielen seltsamen Situationen mit Rails 'integriertem Arel erreicht .
Dadurch werden beide ActiveRecord-Beziehungen mithilfe von oder von Arel zusammengeführt .
Das Zusammenführen hat, wie hier vorgeschlagen, bei mir nicht funktioniert. Der zweite Satz von Beziehungsobjekten wurde aus den Ergebnissen entfernt.
quelle
Es gibt ein Juwel namens active_record_union , das genau das ist, wonach Sie suchen.
Das Beispiel für die Verwendung lautet wie folgt:
quelle
ransack
undacts-as-taggable-on
unter Beibehaltung meinerActiveRecord
Instanzen zu schaffen .So habe ich es "gehandhabt", wenn Sie mit "Zupfen" eine Kennung für jeden der Datensätze erhalten, die Arrays zusammenfügen und schließlich eine Abfrage für diese verknüpften IDs durchführen:
quelle
Wenn Sie über eine Reihe von Aktivaufzeichnungsbeziehungen verfügen und alle zusammenführen möchten, können Sie dies tun
quelle
array.inject(:merge)
funktionierte nicht für eine Reihe von Aktivaufzeichnungsbeziehungen in Schienen 5.1.4. Aberarray.flatten!
tat es.Brute Force es:
quelle