Rails中的after_save回调被多次调用

14

我正在尝试通过混合(mixin)来注入一个after_save回调函数,但是我的rspec测试告诉我当调用create方法时回调被调用了两次。为什么会出现这种情况?

以下rspec测试失败

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

失败信息如下:

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

这是代码

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

Product类还有其他代码,但没有任何其他回调函数。


Rails 版本?我记得在几个版本中有这个问题。 - tadman
如果LinkedAttachment与某个产品相关联,它可能会在创建时触发这个问题。 - charlysisto
我创建了一个干净的 Rails 应用程序 3.0.10,它在那里运行得很好。你能告诉我 LinkedAttachment.delay.create_from_attachment 是什么吗? - p.matsinopoulos
1个回答

11

after_save是事务的一部分,因此如果您有其他需要保存的相关对象,则可能会调用多次。在这种情况下,我通常从after_save回调移动到after_commit回调,它仅在事务完成后运行。


10
这是一个不错的建议,但如果我想确保所有操作(保存和回调操作)作为单个事务一起提交怎么办? - jn29098

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接