J'utilise Rails3, ActiveRecord
Je me demande simplement comment puis-je chaîner les portées avec des instructions OR plutôt que AND.
par exemple
Person.where(:name => "John").where(:lastname => "Smith")
Cela renvoie normalement:
name = 'John' AND lastname = 'Smith'
mais j'aimerais:
`name = 'John' OR lastname = 'Smith'
Réponses:
Vous feriez
À l'heure actuelle, il n'y a pas d'autre support OR par la nouvelle syntaxe AR3 (c'est-à-dire sans utiliser une gemme tierce).
la source
.or
intégré .Selon cette requête d'extraction , Rails 5 prend désormais en charge la syntaxe suivante pour le chaînage des requêtes:
Il existe également un backport de la fonctionnalité dans Rails 4.2 via ce joyau.
la source
Utiliser ARel
la source
Il suffit de publier la syntaxe Array pour la même colonne OU les requêtes pour vous aider.
la source
Mise à jour pour Rails4
ne nécessite pas de gemmes tierces
Ancienne réponse
ne nécessite pas de gemmes tierces
la source
or
ou d'autres opérateurs dans un bloc de texte, dont aucun n'est reflété dans le code d'OP....where_values.join(' OR ')
dans mon cas.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
partie si vos étendues n'ont aucune variable nécessitant une liaison.Vous pouvez également utiliser la gemme MetaWhere pour ne pas mélanger votre code avec des éléments SQL:
la source
Au cas où quelqu'un chercherait une réponse mise à jour à celle-ci, il semble qu'il existe une pull request existante pour l'introduire dans Rails: https://github.com/rails/rails/pull/9052 .
Grâce au patch monkey de @ j-mcnally pour ActiveRecord ( https://gist.github.com/j-mcnally/250eaaceef234dd8971b ), vous pouvez effectuer les opérations suivantes:
La possibilité d'enchaîner les oscilloscopes avec
OR
:Ensuite, vous pouvez trouver toutes les personnes avec un prénom ou un nom de famille ou dont le parent avec le nom de famille
Ce n'est pas le meilleur exemple d'utilisation de ceci, mais simplement essayer de l'adapter à la question.
la source
.or
fonctionnalité de chaîne. J'ai pu utiliser le patch monkey que j'ai mentionné sur Rails> = 3.2; Cependant, vous voudrez peut-être attendre que Rails 5 introduise des modifications de longue date dans votre code.Pour moi (Rails 4.2.5) cela ne fonctionne que comme ceci:
la source
Ce serait un bon candidat pour MetaWhere si vous utilisez Rails 3.0+, mais cela ne fonctionne pas sur Rails 3.1. Vous voudrez peut-être essayer Squeel à la place. Il est fait par le même auteur. Voici comment vous exécuteriez une chaîne basée sur OR:
Vous pouvez mélanger et assortir AND / OR, parmi beaucoup d'autres choses géniales .
la source
Une version mise à jour de Rails / ActiveRecord peut prendre en charge cette syntaxe de manière native. Cela ressemblerait à:
Comme indiqué dans cette demande d'extraction https://github.com/rails/rails/pull/9052
Pour l'instant, il suffit de s'en tenir aux éléments suivants:
la source
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
ne marche pas. Cela devrait être Foo.where (foo: 'bar1'). Or.where (Foo.where (bar: 'bar2'))Rails 4 + Lunette + Arel
J'ai essayé de chaîner des portées nommées avec .or et pas de chance, mais cela a fonctionné pour trouver quoi que ce soit avec ces booléens. Génère du SQL comme
la source
Rails 4
la source
Si vous cherchez à fournir une portée (au lieu de travailler explicitement sur l'ensemble de données), voici ce que vous devez faire avec Rails 5:
Ou:
la source
Si vous ne pouvez pas écrire la clause where manuellement pour inclure l'instruction "ou" (c'est-à-dire que vous souhaitez combiner deux portées), vous pouvez utiliser union:
(source: Union des requêtes ActiveRecord )
Ceci retournera tous les enregistrements correspondant à l'une ou l'autre des requêtes. Cependant, cela renvoie un tableau, pas un arel. Si vous voulez vraiment retourner un arel, vous vérifiez ce point essentiel: https://gist.github.com/j-mcnally/250eaaceef234dd8971b .
Cela fera le travail, tant que cela ne vous dérange pas de patcher les rails de monkey.
la source
Voir également ces questions connexes: ici , ici et ici
Pour les rails 4, basé sur cet article et cette réponse originale
Notez la mise en garde de l'article à la fin:
la source
C'est un moyen très pratique et cela fonctionne bien dans Rails 5:
la source
la
squeel
gemme fournit un moyen incroyablement simple d'accomplir cela (avant cela, j'utilisais quelque chose comme la méthode de @ coloradoblue):la source
Donc, la réponse à la question d'origine, pouvez-vous joindre des portées avec 'ou' au lieu de 'et' semble être "non, vous ne pouvez pas". Mais vous pouvez coder manuellement une portée ou une requête complètement différente qui fait le travail, ou utiliser un cadre différent d'ActiveRecord, par exemple MetaWhere ou Squeel. Pas utile dans mon cas
Je suis 'or' une portée générée par pg_search, qui fait un peu plus que sélectionner, elle inclut la commande par ASC, ce qui fait le désordre d'une union propre. Je veux le 'ou' avec une portée artisanale qui fait des choses que je ne peux pas faire dans pg_search. J'ai donc dû le faire comme ça.
C'est à dire transformer les portées en sql, mettre des crochets autour de chacun d'eux, les unir ensemble, puis find_by_sql en utilisant le sql généré. C'est un peu nul, mais ça marche.
Non, ne me dites pas que je peux utiliser "against: [: name,: code]" dans pg_search, j'aimerais le faire comme ça, mais le champ 'name' est un hstore, que pg_search ne peut pas gérer encore. Ainsi, la portée par nom doit être fabriquée à la main puis fusionnée avec la portée pg_search.
la source
la source