236 votes

Comment retourner une relation ActiveRecord vide?

Si j'ai une portée avec un lambda et qu'il prend un argument, en fonction de la valeur de l'argument, je pourrais savoir qu'il n'y aura pas de correspondance, mais je veux quand même renvoyer une relation, pas un tableau vide:

 scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
 

Ce que je veux vraiment, c’est une méthode «none», à l’opposé de «all», qui renvoie une relation qui peut encore être chaînée, mais qui provoque un court-circuit de la requête.

458voto

steveh7 Points 1665

Il y a maintenant un mécanisme "correct" dans le maître Rails, pas encore publié:

 >> Model.none 
=> #<ActiveRecord::Relation []>
 

https://github.com/rails/rails/commit/75de1ce131cd39f68dbe6b68eecf2617a720a8e4

76voto

steveh7 Points 1665

Une solution plus portable qui ne nécessite pas une colonne « id » et n’est pas supposer qu’il n’y aura une ligne avec un id de 0 :

Je cherche toujours un moyen plus « correct ».

43voto

Nathan Long Points 30303

À venir dans les Rails 4

Dans les Rails 4, un chaînage ActiveRecord::NullRelation sera retourné à partir des appels comme Post.none.

Ni elle, ni enchaîné méthodes, permettra de générer des requêtes à la base de données.

Selon les commentaires:

Le retour de l'ActiveRecord::NullRelation hérite de Rapport et met en œuvre l'Objet Nul motif. C'est un objet avec définit le comportement null et toujours renvoie un tableau vide de dossiers sans quering la base de données.

Voir le code source.

42voto

Brandon Points 1912

Vous pouvez ajouter un champ appelé « none » :

Cela vous donnera un ActiveRecord::Relation vide

Vous pouvez également ajouter il à ActiveRecord::Base dans un initialiseur (si vous voulez) :

Beaucoup de moyens pour obtenir quelque chose comme ça, mais certainement pas la meilleure chose à garder dans un code de base. J’ai utilisé le champ d’application : none lorsque la refactorisation et de trouver que j’ai besoin de garantir une ActiveRecord::Relation vide pendant une courte période.

24voto

bbrinck Points 211
<pre><code></code><p>Est une solution dangereuse car votre portée pourrait être enchaînée sur.</p><p>User.None.First</p><p>retourne le premier utilisateur. Il est plus sûr d’utiliser</p><pre><code></code></pre></pre>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X