2011-04-08 23 views
31

Usar Arel in Rails - Estoy buscando una forma de crear un ActiveRecord::Relation que efectivamente resulte en SELECT * FROM table, que aún puedo manipular más.Rieles/Arel: Seleccionar todos los registros como ActiveRecord :: Relación

Por ejemplo, tengo un modelo que se divide en varias categorías, y regreso el recuento de éstas de la siguiente manera:

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 
} 

Esto funciona bien, y tiene la ventaja de disparar COUNT consultas a MySQL, en lugar de seleccionar realmente los registros.

Sin embargo, ahora necesito incluir registros archivados en los conteos, pero relation = Model.all da como resultado un Array, y estoy buscando un ActiveRecord::Relation.

La única forma en que puedo pensar en hacer esto es model.where(model.arel_table[:id].not_eq(nil)), que funciona, pero parece un poco absurdo.

¿Alguien puede arrojar algo de luz sobre esto?

Respuesta

11

para los carriles 4.1 y superiores: Model.all devuelve una relación (donde antes no lo hizo)

para los carriles 4.0: Model.where(nil)

para los carriles 3.x: Model.scoped

+0

En Rails 4.0.13, 'Model.all' devuelve una relación y' Model.scoped' está en desuso. – Tsutomu

48

Probar relation = Model.scoped. Eso le dará la relación en lugar de los resultados reales.

+0

perfecto, gracias ! Solo puedo aceptar en 10 minutos. – Jeriko

+0

'Model.scoped' está en desuso en Rails 4.X. Ver otra respuesta. –

+1

Gracias de nuevo, acepté la respuesta de Kyle ahora, ya que proporciona una imagen más completa de las diferentes versiones de Rails. – Jeriko

1

Usted quiere:

relation = Model.scoped 

el que si usted ve qué relación es, de hecho, es una ActiveRecord::Relation.

Como se puede ver en esta página:

http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#method-i-scoped

que dice lo siguiente: alcances

anónimas tienden a ser útiles al generar procesalmente complejos consultas, donde pasa intermedia valores (ámbitos) como objetos de primera clase es conveniente.

+0

La única vez que 'scoped' es realmente necesario es cuando desea actuar sobre todos los registros, como' Model.all'. Simplemente haciendo un 'Model.where (: archived => false)' ya solo devolverá un objeto 'ActiveRecord :: Relation'. –

Cuestiones relacionadas