Supposons que j'ai les deux objets suivants:
first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation
last_name_relation = User.where(:last_name => 'Fünke') # ActiveRecord::Relation
est-il possible de combiner les deux relations pour produire un ActiveRecord::Relation
objet contenant les deux conditions?
Remarque: je suis conscient que je peux enchaîner les endroits pour obtenir ce comportement, ce qui m'intéresse vraiment est le cas où j'ai deux ActiveRecord::Relation
objets séparés .
ruby-on-rails
rails-activerecord
arel
Patrick Klingemann
la source
la source
Réponses:
Si vous souhaitez combiner en utilisant
AND
(intersection), utilisezmerge
:Si vous souhaitez combiner en utilisant
OR
(union), utilisez † :or
† Uniquement dans ActiveRecord 5+; pour 4.2 installez le where-or backport.
la source
ActiveRecord::Relation
type?merge
c'est une intersection, pas une union.#or
méthode a été ajoutée à ActiveRecord :: Relation en janvier 2015, et elle fera partie de Rails 5.0 , qui sera disponible fin 2015. Elle permet d'utiliser l'opérateur OR pour combiner les clauses WHERE ou HAVING. Vous pouvez commander HEAD si vous en avez besoin avant la sortie officielle. Voir Merge Pull Request # 16052 @Arcolye @AndrewMarshall @ Aldo-xoen-GiambellucaLes objets de relation peuvent être convertis en tableaux. Cela annule la possibilité d'utiliser des méthodes ActiveRecord par la suite, mais je n'en ai pas eu besoin. J'ai fait ça:
Ruby 1.9, rails 3.2
la source
merge
ne fonctionne pas commeOR
. C'est simplement l'intersection (AND
)J'ai eu du mal avec ce problème pour combiner les objets ActiveRecord :: Relation en un seul et je n'ai trouvé aucune solution de travail pour moi.
Au lieu de chercher la bonne méthode pour créer une union à partir de ces deux ensembles, je me suis concentré sur l'algèbre des ensembles. Vous pouvez le faire de différentes manières en utilisant la loi de De Morgan
ActiveRecord fournit la méthode de fusion (AND) et vous pouvez également utiliser la méthode not ou none_of (NOT).
Vous avez ici (A u B) '= A' ^ B '
MISE À JOUR: La solution ci-dessus est bonne pour les cas plus complexes. Dans votre cas, un peu comme ça suffira:
la source
J'ai pu y parvenir, même dans de nombreuses situations étranges, en utilisant Arel intégré à Rails .
Cela fusionne les deux relations ActiveRecord en utilisant Arel ou .
Merge, comme cela a été suggéré ici, n'a pas fonctionné pour moi. Il a supprimé le 2ème ensemble d'objets de relation des résultats.
la source
Il existe une gemme appelée active_record_union qui pourrait être ce que vous recherchez.
Son exemple d'utilisation est le suivant:
la source
ransack
etacts-as-taggable-on
tout en gardant mesActiveRecord
instances intactes.C'est ainsi que je l'ai "géré" si vous utilisez pluck pour obtenir un identifiant pour chacun des enregistrements, joindre les tableaux ensemble et enfin faire une requête pour ces identifiants joints:
la source
Si vous avez un tableau de relations activerecord et que vous souhaitez toutes les fusionner, vous pouvez faire
la source
array.inject(:merge)
n'a pas fonctionné pour le tableau des relations activerecord dans les rails 5.1.4. Maisarray.flatten!
fait.Brute force il:
la source