1

我希望能够在 DataMapper 中定义一个回调,并在交易中发生这种情况以及伴随的更新。例如:

class Comment
  include DataMapper::Resource

  has n, :updates

  property :id,   Serial
  property :text, String

  after :update do
    self.updates.create(:text => self.text)
  end
end

我认为上面的代码试图做什么很清楚:任何时候Comment更新 a ,也创建一个相应的Update记录。现在,一种可能的情况是,您可以更新帖子,但无论出于何种原因,创建更新都会失败,因此会丢失一些历史记录。所以我真的很希望这种操作发生在一个事务中。

这可能吗?我可以想到一些解决方法(例如,定义自定义update方法);但我很想知道是否有“正确”的方法,或者其他人是否可以想到优雅的方法。

4

1 回答 1

7

为了使用可测试和可扩展的设计进行归档,我建议使用这样的服务对象:

class CommentUpdate

  private_class_method :new

  # Run comment update within transaction
  def self.run(*args)
    Comment.transaction do
      new(*args)
    end
  end

  # Initialize object
  #
  # @param [Comment]
  #   the comment to update
  # @param [String]
  #   the text to set
  # 
  def initialize(comment, text)
    @comment, @text = comment, text
    run
  end

  # Test if update was successful
  def successful?
    @comment.saved?
  end

private

  # Run update
  def run
    @comment.text = @text
    if @comment.save
      @comment.updates.create(:text => @text)
    end
  end
end

# usage
comment = Comment.first
update = CommentUpdate.run(comment, "Some new cool text")
update.successful? # Use this to steer your control flow...
于 2012-11-18T21:49:09.070 回答