我希望能够在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
更新时,也会创建相应的Update
记录。现在,可能的情况是您可以更新帖子,创建更新将失败 - 无论出于何种原因 - 因此某些历史记录将丢失。所以我真的希望在事务中发生这种操作。
这可能吗?我可以想到一些解决方法(例如,定义自定义update
方法);但我很想知道是否有“正确”的方式,或者其他人是否可以想到优雅的方法。
答案 0 :(得分: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...