2012-03-21 11 views
6

Creo que necesito algo parecido a una consulta cargada de carriles con un límite, pero estoy teniendo problemas para encontrar una solución para eso.Rails Eager Load and Limit

En aras de la simplicidad, digamos que nunca habrá más de 30 Person s en el sistema (por lo Person.all es un pequeño conjunto de datos) pero cada persona va a tener más de 2000 comentarios (por lo Person.include(:comments) habría una gran conjunto de datos).

asociación de padres

class Person < ActiveRecord::Base 
    has_many :comments 
end 

asociación Niño

class Comment < ActiveRecord::Base 
    belongs_to :person 
end 

necesito para consultar una lista de Person s e incluir sus comments, pero sólo necesita 5 de ellos.

me gustaría hacer algo como esto:

padres Limited asociación

class Person < ActiveRecord::Base 
    has_many :comments 
    has_many :sample_of_comments, \ 
    :class_name => 'Comment', :limit => 5 
end 

controlador

class PersonController < ApplicationController 
    def index 
    @persons = Person.include(:sample_of_comments) 
    end 
end 

Desafortunadamente, this article estados: "Si una carga ansiosa asociación con una opción especificada: límite, será i gnored, devolviendo todos los objetos asociados "

¿Hay alguna forma de evitar esto? ¿O estoy condenado a elegir entre desear cargar miles de objetos ActiveRecord innecesarios y una consulta N + 1? También tenga en cuenta que este es un ejemplo simplificado. En el mundo real, tendré otras asociaciones con Person, en la misma acción index con el mismo problema que comments. (fotos, artículos, etc.).

+0

independientemente de carriles o activerecord, en primer lugar tratar de llegar a la par de LSQ que usted piensa que le dará su conjunto de resultados. si no puede, tampoco puede ninguna biblioteca de orm. – choonkeat

Respuesta

0

Independientemente de lo que "ese artículo" Dicho esto, el problema está en SQL no se puede acotar la segunda consulta SQL (de carga con ganas) de la manera deseada en este escenario, simplemente mediante el uso de un estándar LIMIT

puede, sin embargo, añadir una nueva columna y realizar una cláusula WHERE en lugar

  1. Cambiar la segunda asociación a Person has_many :sample_of_comments, conditions: { is_sample: true }
  2. Agregar una tabla is_sample columna para comments
  3. Añadir un gancho Comment#before_create que asigna is_sample = person.sample_of_comments.count < 5
+0

Hola, choonkeet, no es una mala idea. Desafortunadamente, para cada comentario que la persona crea, el conjunto de comentarios que se considerarían muestras cambiaría en uno. Supongo que al hacer algún tipo de actualización, todas las declaraciones funcionarían para esto, pero parece una escritura difícil. Ejemplo: la persona tiene 5 comentarios, todos son "muestras". La persona crea un sexto comentario.Ahora, el comentario 1 ya no debe formar parte del conjunto de muestras y de 2 a 6 son ahora los comentarios de muestra establecidos. –