He estado intentando asociaciones de carga ansiosas basadas en algún ámbito en mi aplicación rails3, pero no he podido encontrar ninguna solución.Eagerloading con scoping en rails3
Mi aplicación tiene siguientes modelos:
class Project
has_many :entries
has_many :to_dos
class ToDo
has_may :entries
has_many :tasks
belongs_to :project
class Task
has_many :entries
belongs_to :to_do
class Entry
belongs_to :project
belongs_to :to_do
belongs_to :task
# options format: {:from_date=>(Date.today-1.week), :to_date=>(Date.today+1.week), :user_id=>60}
scope :filtered_list, lambda { |options|
condition = options[:user_id].nil? ? "true" : "user_id = #{options[:user_id]}"
condition += options[:from_date].nil? ? "" : " AND entry_date >= '#{options[:from_date]}'"
condition += options[:to_date].nil? ? "" : " AND entry_date <= '#{options[:to_date]}'"
where(condition)
}
Y en proyectos índice # Tengo siguiente código para obtener todos los proyectos de un usuario:
@projects = current_user.projects.includes(:entries, :to_dos =>[:entries, :tasks => :entries])
Recupera todos los proyectos del usuario, junto con ganas de cargar las asociaciones. Entonces, cuando realizo el siguiente ciclo para obtener todas las entradas dentro del proyecto, no se activa ninguna nueva consulta.
def all_entries(options)
entries = self.entries
self.to_dos.each do |d|
entries += d.entries
d.tasks.each do |t|
entries += t.entries
end
end
end
Como esta carga ansiosa recupera todas las entradas, es demasiada información de la que realmente necesitaba. Así que traté de aplicar algunas condiciones a las entradas ansiosas cargadas, pero no pude encontrar ninguna solución. Estaba buscando algo como:
@projects = current_user.projects.includes(:entries.filtered_list(options), :to_dos =>[:entries.filtered_list(options), :tasks => :entries.filtered_list(options)])
De modo que solo se carguen las entradas que cumplan algunas condiciones.
¿No podemos usar el alcance con la carga ansiosa? Por favor, ayúdenme a usar eagerloading junto con el alcance.