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?

31
demandé sur Jeriko 2011-04-08 17:38:42

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

11
répondu Kyle Heironimus 2015-01-30 04:16:36

Essayez relation = Model.scoped. Cela vous donnera la relation au lieu des résultats réels.

48
répondu Dylan Markow 2011-04-08 13:40:40

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.

1
répondu Mike Lewis 2011-04-08 13:56:31