2010-05-20 14 views
7

He revisado las fuentes de Arel y algunas de las fuentes ActiveRecord para Rails 3.0, pero parece que no puedo obtener una buena respuesta para mí sobre si Arel cambiará nuestra capacidad de usar includes(), cuando construyendo consultas, para mejor.¿Cómo afectará ActiveRelation a las capacidades de include() de rieles?

Hay casos en los que uno podría querer modificar las condiciones en un registro activo: incluir consulta en 2.3.5 y antes, para los registros de asociación que serían devueltos. Pero hasta donde yo sé, esto no es programáticamente defendible para todos: incluye consultas:

(sé que AR-find-includes make t # {n} .C# {m} cambia el nombre de todos los atributos, y podría agregar condiciones a estas consultas para limitar los resultados de los conjuntos combinados, pero otros hacen n_joins + 1 número de consultas sobre los conjuntos de identificadores iterativamente, y no estoy seguro de cómo se podría hackear AR para editar estas consultas iteradas.)

Will Arel nos permite construir consultas ActiveRecord que especifican los objetos de modelo asociados resultantes al usar includes()?

Ex:

User :has_many posts(has_many :comments) 

User.all(:include => :posts) #say I wanted the post objects to have their 
#comment counts loaded without adding a comment_count column to `posts`. 

#At the post level, one could do so by: 
posts_with_counts = Post.all(:select => 'posts.*, count(comments.id) as comment_count', 
     :joins => 'left outer join comments on comments.post_id = posts.id', 
     :group_by => 'posts.id') #i believe 

#But it seems impossible to do so while linking these post objects to each 
    #user as well, without running User.all() and then zippering the objects into 
    #some other collection (ugly) 
    #OR running posts.group_by(&:user) (even uglier, with the n user queries) 
+0

Steven Xu efectivamente hizo mi pregunta en su forma más básica. http://stackoverflow.com/questions/4908878/how-do-i-get-rails-to-eager-load-counts –

Respuesta

3

ActiveRecord :: La relación es una envoltura bastante débil alrededor de Base # find_by_sql, por lo que: include las consultas no se extienden de ninguna manera por su inclusión.

+0

Lo cual reduce la pregunta a: http://stackoverflow.com/questions/4908878/how-do-i-get-rails-to-eager-load-counts –

4

¿Por qué no utilizan realmente AREL en su núcleo. Una vez que llegue al alcance de la tabla real, puede usar Arel :: Relation, que es COMPLETAMENTE diferente de la implementación de ActiveRecord. Realmente creo que ActiveRecord :: Relation es una implementación COMPLETAMENTE diferente (y reventada) de un contenedor alrededor de Arel :: Relation & Arel :: Table. Elijo usar Arel en su núcleo al hacer Thing.scoped.table (Arel :: Table) que es el estilo de registro activo O Arel :: Table.new (: table_name) que me da una nueva Arel :: Table (my metodo preferido). De esto puedes hacer lo siguiente.

posts = Arel::Table.new(:thing, :as => 'p') #derived relation 
comments = Arel::Table.new(:comments, :as => 'c') # derived relation 
posts_and_comments = posts.join(comments).on(posts[:id].eq(:comments[:id])) 

# now you can iterate through the derived relation by doing the following 
posts_and_comments.each {...} # this will actually return Arel::Rows which is another story. 
# 

Un Arel :: fila devuelve una definición verdadera de una tupla del conjunto que consistirá en una Arel :: Header (conjunto de Arel :: Atributos) y una tupla.

También un poco más prolijo, la razón por la que uso Arel en su núcleo es porque realmente me expone el modelo relacional que es el poder detrás de ActiveRelation. Me he dado cuenta de que ActiveRecord está exponiendo como el 20% de lo que Arel tiene para ofrecer y tengo miedo de que los desarrolladores no se den cuenta de esto ni comprendan el verdadero núcleo del álgebra relacional. Usar el hash de condiciones es para mí una "vieja escuela" y una programación de estilo ActiveRecord en un mundo de álgebra relacional. Una vez que aprendemos a distanciarnos del enfoque basado en el modelo de Martin Fowler y adoptar el enfoque basado en el modelo relacional de E.F. Codd, esto es lo que los RDBMS han intentado hacer durante décadas, pero se han equivocado.

Me he tomado la libertad de comenzar una serie de aprendizaje de siete partes sobre Arel y Algebra Relacional para la comunidad de ruby. Estos consistirán en videos cortos que van desde el principiante absoluto hasta técnicas avanzadas como las relaciones de autorreferencia y el cierre en la composición. El primer video está en http://Innovative-Studios.com/#pilot Por favor, hágame saber si necesita más información o esto no fue lo suficientemente descriptivo para usted.

El futuro se ve brillante con Arel.

+0

Gracias por mencionar ActiveRecord :: Relation. Ese comentario me condujo aquí: http://metautonomo.us/2010/05/11/activerecord-relation-vs-arel/, que me acerca un poco más a la comprensión del sistema de envoltura. –

+0

"¿Por qué realmente no usas AREL en su núcleo?" Porque me gustaría usar formtastic, para que los diseñadores con los que trabajo puedan editar formularios de la manera que quieran. No estoy listo para abandonar ActiveRecord todavía. –

+0

No creo que esto importe; la respuesta, quiero decir. Estoy completamente de acuerdo en que usar arel directamente es casi obligatorio para consultas más avanzadas, pero no está haciendo lo mismo que usar las inclusiones tradicionales con ActiveRelation, por lo que puedo decir. – wkhatch

1

no

Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all 

es lo que está buscando?(tomado del docs oficial)

+0

Perdón, no debo haber sido claro. Lo que estaba pidiendo es modificar los miembros cargados en el objetivo de la asociación incluida. Por ejemplo, para contar el número de comentarios para cada publicación sin cargar los objetos de comentario de la base de datos. –

+0

No he probado su ejemplo, pero creo que esa consulta también reduciría el conjunto de publicaciones a solo aquellas que tenían un comentario marcado como aprobado también. –

+0

Avíseme sobre cómo puedo editar la pregunta para que todo esto sea más obvio. –

Cuestiones relacionadas