【问题标题】:ActiveRecord#save: `retry` breaks "autosave" for associationsActiveRecord#save: `retry` 打破关联的“自动保存”
【发布时间】:2021-07-09 16:43:15
【问题描述】:

我在 ActiveRecord 模型上覆盖 save 以处理边缘情况:

class A < ActiveRecord::Base
  belongs_to :b

  def save *args
    super
  rescue ActiveRecord::StatementInvalid => ex
    log_warning
    retry unless @foo
    throw ex
  end
end

a = A.new
a.build_b
a.save

我发现当save 函数第二次执行时(因为retry),我得到一个与关联记录b 相关的MySQL 错误:

ActiveRecord::StatementInvalid: Mysql2::Error: Field 'created_at' doesn't have a default value: INSERT INTO bs VALUES ()

使用断点我可以看到在retry 之后,对bActiveRecord#_create_record (see source) 调用有一个空数组([]) 用于保存属性,而它是["full_name","company","id","owner_id","created_at","updated_at"] 第一次调用。

为什么retry 会破坏关联记录的自动保存?我该怎么办?

上面的链接适用于 ActiveRecord 4.2.11.3,这是我正在从事的项目的版本。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 activerecord


    【解决方案1】:

    如果我是你,我不会覆盖 save 方法。 我宁愿使用around_save 回调。

    class A < ActiveRecord::Base
      around_save :saving_retry
    
      def saving_retry
        yield
      rescue ActiveRecord::StatementInvalid => ex
        log_warning
        save unless @foo
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 2013-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      相关资源
      最近更新 更多