为什么我不能调用self.save!在 Ruby DataMapper 内部:创建回调?

Why can't I call self.save! inside of a Ruby DataMapper after :create callback?

我有以下最小示例 DataMapper 模型:

# model.rb
require 'data_mapper'

class Job
  include DataMapper::Resource
  after :create, :create_id_based_data

  property :id, Serial
  property :magicNumber, String

  def create_id_based_data
    self.magicNumber =  "#{self.id}_#{Random.rand()}"
    self.save!
  end
end

DataMapper.setup(:default, 'sqlite::memory:')
DataMapper.auto_migrate!

如果我运行irb中的代码,"magicNumber"没有保存到数据库中:

irb -r ./model.rb 
2.2.1 :001 > Job.all
 => [] 
2.2.1 :002 > Job.create
 => #<Job @id=1 @magicNumber="1_0.6245356525078689"> 
2.2.1 :003 > Job.all
 => [#<Job @id=1 @magicNumber=nil>]

我的理解是 DataMapper 会阻止在 save 回调中重复调用 save,但是在 [=17= 中不应允许 save 调用] 钩后?即使不允许正常的 save 调用,save! 调用不应该绕过所有回调并因此被允许吗?

查看 this bug report,防止 save 调用循环的机制 (run_once) 似乎仍在发挥作用。不清楚这是否是错误。使用 save_self 提供您想要的行为,但代价是使用半 public API.

# model.rb                         
require 'data_mapper'

class Job
  include DataMapper::Resource
  after :create, :create_id_based_data

  property :id, Serial
  property :magicNumber, String

  def create_id_based_data
    self.magicNumber =  "#{self.id}_#{Random.rand()}" 
    save_self(false)
  end
end

DataMapper.setup(:default, 'sqlite::memory:')
DataMapper.auto_migrate!

结果:

irb -r ./model.rb
2.1.0 :001 > Job.all
 => []
2.1.0 :002 > Job.create
 => #<Job @id=1 @magicNumber="1_0.7816860975338344">
2.1.0 :003 > Job.all
 => [#<Job @id=1 @magicNumber="1_0.7816860975338344">]
2.1.0 :004 >