raw rails query left inner includes active ruby-on-rails activerecord eager-loading

ruby-on-rails - left - raw query ruby on rails



¿Cómo determinar si la Asociación de rieles está cargada de entusiasmo? (7)

¿Alguien sabe una forma de determinar si una asociación de Rails ha estado ansiosamente cargada?

Mi situación: tengo un conjunto de resultados donde a veces una de las asociaciones está ansiosamente cargada, y otras no. Si no está lleno de ansias, entonces quiero buscar asociaciones usando la búsqueda de ActiveRecord. Si está ansiosamente cargada, quiero usar detectar.

Por ejemplo, supongamos que tengo una matriz "has_many" de objetos shipping_info en mi modelo de artículo. Entonces:

Si el artículo está ansioso de carga, la carga más eficiente es:

item.shipping_infos.detect { |si| si.region == "United States" }

Si el artículo no está ansioso de cargarse, la carga más eficiente es:

item.shipping_infos.where(region: "United States").first

Pero a menos que sepa si está ansiosamente cargada, no sé qué código llamar para obtener el registro de manera eficiente. Si utilizo el primer método cuando no estaba ansioso de cargar, entonces tengo que buscar más registros de DB de los necesarios. Y si utilizo el segundo método cuando estaba ansioso de cargar, mis ansiosos objetos cargados se ignoran.


Eche un vistazo a la gema Bullet. . Esto le dirá cuándo debe y no debe usar la carga ansiosa.


La solución a este problema debería ser foo.association(:bla).loaded? PERO funciona incorrectamente, comprueba y marca la asociación como sucia:

class Foo; has_one :bla, :autosave => true end foo.association(:bla).loaded? #=> false foo.save # saves foo and fires select * from bla

Así que he agregado la siguiente extensión a ActiveRecord:

module ActiveRecord class Base def association_loaded?(name) association_instance_get(name).present? end end end

y ahora:

class Foo; has_one :bla, :autosave => true end foo.association_loaded?(:bla) #=> false foo.save # saves foo


Puede detectar si una sola asociación ha sido cargada o no con loaded_ foo ? Por ejemplo, si shipping_info era una asociación belongs_to, entonces item.loaded_shipping_info? volverá verdadero cuando haya sido ansiosamente cargado. Curiosamente, parece devolver nil (en lugar de falso) cuando no se ha cargado (en Rails 2.3.10 de todos modos).


Sugiero usar item.association_cache.keys que proporcionará una lista de las asociaciones cargadas ansiosas. ¿Así que incluye item.association_cache.keys.include? : nombre_de_asociación




item.shipping_infos.loaded? Te contaré.

Debo decir, sin embargo: este camino conduce a la locura ... ¿antes de escribir el código que las pruebas loaded? para decidir entre #detect y #find , asegúrese de que esta instancia realmente importa, en relación con todo lo demás que está sucediendo.

Si esto no es lo más lento que hace su aplicación, agregar rutas de código adicionales agrega complejidad innecesaria. El hecho de que pueda desperdiciar un poco de esfuerzo en la base de datos no significa que deba solucionarlo, probablemente no importe de manera medible.