2011-09-29 25 views
9

Estoy intentando inyectar una devolución de llamada after_save a través de un mixin, pero mis pruebas rspec me dicen que se llama a la devolución de llamada dos veces cuando se llama al método create. ¿Por qué se llama al método dos veces?Rails after_save callback se llama varias veces

La siguiente prueba rspec falla

it 'should call callback' do 
    Product.any_instance.should_receive(:update_linkable_attachments).once 
    Product.create(:name=>'abc') 
end 

El mensaje de error es:

Failure/Error: Unable to find matching line from backtrace 
    (#<Product:0xb7db738>).update_linkable_attachments(any args) 
     expected: 1 time 
     received: 2 times 

Aquí está el código

clase
module MainModuleSupport 
    def self.included(base) 
    base.instance_eval("after_save :update_linkable_attachments") 
    end 

    def update_linkable_attachments 
    LinkedAttachment.delay.create_from_attachment self 
    end 
end 

class Product < ActiveRecord::Base 
    include MainModuleSupport 
    ... 

end 

El producto tiene otro código, pero no tiene ningún otras devoluciones de llamada.

+0

Versión de rieles? Creo que hubo un problema para esto en algunos lanzamientos. – tadman

+0

Estoy ejecutando la versión 3.0.8 –

+0

LinkedAttachment podría estar activando esto en la creación si está relacionado con el producto de alguna manera – charlysisto

Respuesta

5

after_save es parte de la transacción y, por lo tanto, se puede invocar más de una vez, siempre que tenga otros objetos asociados que también se deben guardar. En casos como este, generalmente me muevo de la devolución de llamada after_save a la devolución de llamada after_commit, que se ejecuta solo después de que la transacción se haya completado.

+3

Esta es una buena sugerencia, pero ¿qué ocurre si quiero asegurarme de que todas las operaciones (las operaciones de guardado y de devolución de llamada) se realizan juntas como parte de una sola transacción? – jn29098

Cuestiones relacionadas