Rails / Arel: sélection de tous les enregistrements en tant que Relation ActiveRecord::
En utilisant Arel dans Rails-je cherche un moyen de créer un ActiveRecord::Relation
qui aboutit effectivement à SELECT * FROM table
, que je peux encore manipuler plus loin.
Par exemple, j'ai un modèle qui est divisé en plusieurs catégories, et je retourne des comptes pour ceux-ci de la manière suivante:
relation = Model.where(:archived => false) # all non-archived records
record_counts = {
:total => relation.count,
:for_sale => relation.where(:for_sale => true).count
:on_auction => relation.where(:on_auction => true).count
}
Cela fonctionne bien, et a l'avantage de lancer des requêtes COUNT
sur MySQL, plutôt que de sélectionner les enregistrements eux-mêmes.
Cependant, je dois maintenant inclure les enregistrements archivés dans le compte, mais relation = Model.all
entraîne un Array
, et je cherche un ActiveRecord::Relation
.
La seule façon de penser à faire cela est model.where(model.arel_table[:id].not_eq(nil))
, qui fonctionne, mais semble un peu absurde.
Quelqu'un peut-il faire la lumière sur cela?
3 réponses
Pour Rails 4.1 et supérieur: Model.all
renvoie une relation (alors qu'elle ne l'était pas auparavant)
Pour Rails 4.0: Model.where(nil)
Pour Rails 3.x: Model.scoped
Essayez relation = Model.scoped
. Cela vous donnera la relation au lieu des résultats réels.
Vous voudriez:
relation = Model.scoped
Qui si vous voyez quelle relation est, c'est en fait un ActiveRecord::Relation
.
Comme vous pouvez le voir sur cette page:
Http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#method-i-scoped
Il dit ce qui suit:
Les étendues anonymes ont tendance à être utiles lorsque la procédure générant complexe requêtes, où passer intermédiaire valeurs (étendues) autour comme première classe objets est pratique.