Comment faire une or
requête dans Rails 5 ActiveRecord? En outre, est-il possible de chaîner or
avec des where
requêtes ActiveRecord?
ruby-on-rails
ruby
activerecord
ruby-on-rails-5
rails-activerecord
KM Rakibul Islam
la source
la source
Réponses:
La possibilité de chaîner la
or
clause avec lawhere
clause dans laActiveRecord
requête sera disponible dans Rails 5 . Voir la discussion associée et la demande d'extraction .Ainsi, vous pourrez effectuer les opérations suivantes dans Rails 5 :
Pour obtenir un
post
avecid
1 ou 2:Quelques autres exemples:
(A && B) || C:
(A || B) && C:
la source
Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))
cela devrait créer (a || b) && (c || d)ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Nous n'avons pas besoin d'attendre que les rails 5 utilisent cette
OR
requête. Nous pouvons également l'utiliser avecrails 4.2.3
. Il y a un backport ici .Merci à Eric-Guo pour la gemme où-ou , maintenant nous pouvons ajouter cette
OR
fonctionnalité en>= rails 4.2.3
utilisant également cette gemme.la source
(Juste un ajout à la réponse de KM Rakibul Islam.)
En utilisant des étendues, le code peut devenir plus joli (selon les yeux qui regardent):
la source
J'avais besoin de faire un
(A && B) || (C && D) || (E && F)
Mais dans
5.1.4
l'état actuel de Rails , cela est trop compliqué à accomplir avec la chaîne ou Arel. Mais je voulais toujours utiliser Rails pour générer autant de requêtes que possible.J'ai donc fait un petit hack:
Dans mon modèle, j'ai créé une méthode privée appelée
sql_where
:Ensuite, dans mon champ d'application, j'ai créé un tableau pour contenir les OR
Ce qui produira le résultat de la requête prévue:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
.Et maintenant, je peux facilement combiner cela avec d'autres portées, etc. sans aucun OR erroné.
La beauté étant que mon sql_where prend des arguments normaux de clause where:
sql_where(name: 'John', role: 'admin')
générera(name = 'John' AND role = 'admin')
.la source
.merge
comme équivalent de &&, et construire un arbre approprié pour capturer vos parents. Quelque chose comme ...(scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
, en supposant que chacune des portées ressemble à quelque chose commeModel.where(...)
Rails 5 a la capacité de
or
clause avecwhere
. Par exemple.la source