2009-07-24 5 views
13

carga Eager es agradable con la atribuyo incluyen¿Rails ansiosos por cargar los conteos?

Post.find(:all, :include => :author) 

Me pregunto si es posible también el recuento de carga ansiosos, como si quería obtener el número de comentarios para cada puesto, sin cargar todos los mismos comentarios?

tal vez algo como

Post.find(:all, :include => [:author, "count(comments)") 

supongo que podría utilizar una columna count_cache. Pero hacerlo todo en una inclusión sería realmente hermoso, si es posible.

Puntos de bonificación extra si alguien puede mostrar cómo no solo obtener el conteo, sino también poner algunas condiciones, como el recuento de solo las publicaciones que se aprobaron.

+0

Esto se expandió más adelante en esta pregunta: http://stackoverflow.com/questions/4908878/how-do-i-get-rails-to-eager-load-counts que está estrechamente relacionado con: http://stackoverflow.com/questions/2870521/how-will-activerelation-affect-rails-includes-s-capabilities (que es cómo lo encontré). –

Respuesta

-6

Al menos en MySQL, es más rápido hacer esto como dos llamadas separadas porque se evita la unión. Sé que esto no responde a su pregunta, pero parece como si estuviera tratando de obtener una mejor velocidad y haciendo

Post.find ... 

Entonces

post.comments.count 

es más rápido y más eficiente de la memoria (para la base de datos) que si recuperas ambas en una consulta.

+4

Bueno, una de las principales razones para utilizar carga ansiosa es evitar N + 1 consultas. – MrTheWalrus

+3

Esto induce una consulta N + 1 y no responde la pregunta. – davidgoli

24

que ya deben cargarse uso

post.comments.length 

que estaba teniendo este mismo problema porque estaba usando .count

+2

No creo que esto sea lo que está buscando. Esto cargará todas las entradas en la asociación de comentarios y luego las contará. Quiere usar SQL para extraer ansiosamente el conteo sin cargar los objetos. (O al menos así es como lo entiendo). – Mike

+0

Tienes razón Mike. –

+1

Esta fue la solución que estaba buscando. En la página de índice de publicaciones donde me gustaría iterar sobre la colección y mostrar el recuento de comentarios, esto evita generar una solicitud de conteo en cada ciclo (siempre que los comentarios hayan sido cargados con entusiasmo junto con las publicaciones). Gracias :-) – Renra

2

Prueba esto:

Comment.count(:group => :post) 

para filtrar por condiciones:

Comment.count(:group => :post, :conditions => {:approved => true }) 

Esto devolverá valores hash con publicaciones como claves y la cantidad de comentarios como valores.

+0

No es exactamente lo que estoy buscando. Sí, puedes hacerlo en una llamada aparte como esta. Pero no creo que puedas hacerlas en una asociación como yo quería. Probablemente tenga que usar la columna count_cache. –

3

Construyendo fuera de la respuesta de avaynshtok, la siguiente técnica solo debe hacer 2 llamadas a la base de datos.

# ./app/controllers/posts_controller.rb 

def index 
    # First load the posts 
    @posts = Post.all 

    # Then you can load a hash of author counts grouped by post_id 
    # Rails 3 version: 
    @comment_counts = Comment.count(:group => :post_id) 
    # Rails 4 version: 
    # @comment_counts = Comment.group(:post_id).count 
end 

A continuación, en su opinión

<!-- ./app/views/posts/index.html.erb --> 

<% @posts.each do |post| %> 
    <!-- reference the count by the post.id --> 
    post_count: <%= @comment_counts[post.id] %> 
<% end %> 
0

Me acabo de encontrar con este reto y lo resolvió de esta manera:

def trainee_counts 
    @trainee_counts ||= Hash[Trainee.group(:klass_id).count] 
end 

    # where the count is needed 
    trainee_counts[klass_id].to_i 

Una llamada a la base de datos y no se carga aprendices.

Cuestiones relacionadas