2012-03-09 10 views
12

Tengo una configuración simple de User y UserProfile modelo con el usuario has_one :user_profile y perfil de usuario belongs_to :user.Rieles - secuencia de ejecución de después de crear devolución de llamada y atributos anidados

Pero no puedo entender cómo Rails define el orden de ejecución after_create callback y accepts_nested_attributes_for definidos en mi modelo. Consideremos estos dos casos.

Caso 1:

class User < ActiveRecord::Base 
    has_one :user_profile 
    accepts_nested_attributes_for :user_profile 
    after_create :test_test 
end 

Ahora, si puedo crear un usuario (con user_profile_attributes picadillo también) a través de la consola, la devolución de llamada after_create se activa cuando el usuario y se crea su perfil de usuario.

Caso 2: Si el after_create se coloca en la parte superior,

class User < ActiveRecord::Base 
    after_create :test_test 
    has_one :user_profile 
    accepts_nested_attributes_for :user_profile 
end 

la devolución de llamada se activa después de que un usuario ha sido creado, pero antes de crear un perfil de usuario.

Es así como se espera que funcione. ¿Qué hace Rails internamente aquí? ¿La secuencia de ejecución simplemente está determinada por el orden del código?

¿Por dónde empiezo a profundizar o depurar esto?

+1

Lo probaría de nuevo, el orden del código en forma de devoluciones de llamada no tiene nada que ver con el orden de ejecución .. – Rabbott

+0

@Rabbott - ¡Lo aprecio! – prasvin

+0

Usar 'inverse_of' puede ser útil para resolver dependencias y problemas de guardado en la creación o en el guardado. p.ej. 'has_one: user_profile, reverse_of:: user' – ybart

Respuesta

10

El orden de las declaraciones en su modelo puede tener un impacto en el orden de ejecución del código. Esta es una fuente de varias cosas raras. (por ejemplo, actualmente las definiciones de devolución de llamada y las asociaciones has_and_belongs_to_many dependen del orden: https://github.com/rails/rails/pull/8674)

Para solucionar el problema, debe explorar la fuente de los raíles. Debido a que su problema tiene que ver con el orden de ejecución, las devoluciones de llamada y los atributos anidados Me gustaría empezar por leer sobre: ​​

Esto le da a los antecedentes necesarios para excavar más hondo. Notará que accepts_nested_attributes_for llama al add_autosave_association_callbackshttps://github.com/rails/rails/blob/master/activerecord/lib/active_record/autosave_association.rb#L173 Este método agrega una devolución de llamada after_create y, por lo que sé, las devoluciones de llamada se ejecutan en orden de definición.

+2

Gracias. Esto era exactamente con lo que me estaba encontrando. Mi modelo tenía after_create callbacks en ejecución y se colocaron ANTES de las definiciones has_many. En el after_create estaba actualizando un atributo con update_attribute (en ciertos casos) que estaba causando que el resto de la cadena has_many fallara al actualizar, lo que significa que mi has_many: a través de las relaciones NO se guardaba en absoluto. Mover el after_create DESPUÉS de que las definiciones de mi relación resolvieran el problema. Loca. ¡¡¡Gracias!!! –

+0

El problema (no tan oscuro?) Discutido en esta publicación es una cosa.Fui mordido por esto, y arreglé el problema moviendo la definición de devolución de llamada 'after_update' por debajo de las definiciones has_many & accepts_nested_attributes_for, en mi modelo, como se describió anteriormente. –

+0

@DonnFelker sí, moviendo mi 'after_create' debajo de mi' accepts_nested_attributes' también lo solucionó, gracias. – eggie5

Cuestiones relacionadas