9

我正在尝试调试一些代码。一个奇怪的部分是before_save回调被调用了两次,尽管我只打算保存一次对象。

为了追踪这是如何发生的,我在类中定义了这些方法:

%w[save save!].each do |method_name|
  define_method(method_name) do |*args|
    puts "who called '#{method_name}'? #{caller.first}"
    super(*args)
  end
end

从这个输出中,我只看到一个持久性调用。

我相信这是导致 ActiveRecord 持久savesave!对象的唯一方法。据我所知,其他持久化方法依赖于这两种方法之一;例如,update_attributes来电saveupdate_attributes!来电save!等。

是否有任何方法在不调用save或的情况下保留 ActiveRecord 对象save!

(我正在使用 ActiveRecord 3.2.13)

更新

查看 3.2.13 的 Rails 源代码,既保存保存!调用私有方法create_or_update来完成他们的工作。我过去常常git grep寻找其他出现的测试,create_or_update并且只找到测试和callbacks.rb包含它的东西。

create_or_update反过来,依赖于klass.connection.updateself.class.unscoped.insert

create_or_update所以也许问题是除了持久化 ActiveRecord 对象之外是否还有其他东西。

4

1 回答 1

1

查看 ActiveRecord 3.2.13 callbacks.rb,第 264 行。每当调用 create_or_update 时都会触发保存回调。该方法仅由 save 和 save! 调用。update_column 绕过 create_or_update 并使用 update_all 代替。first_or_create 调用 create,后者调用 save。

我会在两个地方寻找:1.保存是否会触发关联记录中的保存,尝试再次保存原始模型?如果是这样,我希望 save 方法会再次被调用,所以很可能不是这样。2. 你确定 before_save 是被调用的吗?假设您有“before_save :do_something”,并且 do_something 被调用了两次。在保存的上下文之外是否有任何调用 :do_something 的东西?或者另一个 before_save 回调调用 :do_something 除了回调?

于 2013-06-08T03:05:33.850 回答