2011-06-25 11 views
9

En la documentación para la carga ansiosa se afirma que:¿Cómo se hace la carga ansiosa con límites?


Si la carga ansiosa una asociación con una especificada: opción de límite, será ignorado, volviendo todos los objetos asociados:

class Picture < ActiveRecord::Base 
    has_many :most_recent_comments, :class_name => 'Comment', 
            :order => 'id DESC', :limit => 10 
end 

Picture.find (: first,: include =>: most_recent_comments) .most_recent_comments # => devuelve todos los comentarios asociados.


Si este es el caso, entonces, ¿cuál es la mejor manera de alcanzar el "límite" en la carga?

Digamos que estamos ansiosos de cargar las últimas 10 publicaciones de blog en la página principal de un blog, claramente no las queremos todas, así que ¿debería especificarse el límite y el orden de la colección de publicaciones?

Además de eso, ¿se pueden especificar las mismas condiciones en los elementos que están cargados en profundidad, por ejemplo, solo se muestran los primeros tres comentarios en cada entrada de blog?

Blog.find(:blog_id, :include => {:posts => :comments }) 
+1

Tome un vistazo a esta respuesta ... http://stackoverflow.com/questions/9808674/rails-eager-load-and-limit – user1896290

Respuesta

0

Puede utilizar esta construcción: Picture.find(:first, :include => :most_recent_comments).most_recent_comments.limit(10)

Ver más en AR guide

+6

El patrón que has descrito no restringe la consulta original, solo los datos devueltos de ella. El desafío es restringir la consulta original de modo que no cargue ** todas ** las publicaciones de blog en la memoria –

4

Creo que esto se debe a que el comando LIMIT en SQL no se traduce bien a lo que está tratando de hacer. LIMIT limitará las filas totales devueltas por la consulta. No estás tratando de hacer eso sin embargo. Está intentando limitar el número de filas unidas por cada imagen devuelta. Para lograr este efecto, tendría que usar SQL complejo, que podría ser difícil de optimizar si sus tablas son grandes. En ese punto consideraría por qué estás tratando de limitar las filas ansiosas cargadas.

Si la cantidad máxima de comentarios ansiosos cargados es manejable (< 2000 más o menos), probablemente no debería preocuparse por la limitación en el extremo SQL.

Si solo está cargando 10 publicaciones, no consideraría la carga ansiosa. No esperaría que 10 consultas adicionales ralentizaran mucho las cosas, y a qué hora añadieron, podría compensar con otras técnicas de optimización como el almacenamiento en caché.

Debe dejar que los ámbitos hagan el trabajo sucio por usted, no por la asociación. Esto promueve la reutilización, el mantenimiento, la legibilidad.Ejemplo:

Class Picture < ActiveRecord::Base 
    has_many :comments, :order => 'id DESC' do 
    def recent 
     limit(10) 
    end 
    end 
end 

De esa manera .comments está ahí cuando lo necesite, y se puede también alcance abajo como esto:

@picture.comments.recent 
1

he utilizado will_paginate ayudar a mí, junto con la carga ansiosa (using includes) ya que tengo que cargar muchos modelos asociados en una sola toma sin usando limit

Image.includes(:user,:tags).where("user_id !=?",current_user.id).paginate(:page => params[:page], :per_page => 15) 

O (sin will_paginate (usandolimit)

Image.includes(:user,:tags).where("user_id !=?",current_user.id).limit(30).order("created_at ASC") 

... darle una try..hope ayuda.

Cuestiones relacionadas