让我们说我们有以下情形:什么是一些常见的模式来确保跨多个系统的Rails模型的数据持久性?
class MyModel < ActiveRecord::Base
after_save :throw_after_save
after_commit :throw_after_commit
private
def throw_after_save
raise "raising on after_save"
end
def throw_after_commit
raise "raising on after_commit"
end
end
class MyController < ApplicationController
def callback
begin
MyModel.new(params).save
rescue
flash[:alert] = "Failed persisting to external system. Try again."
Airbrake.notify(
error_class: "External System Persistence",
error_message: "External System Persistence: Failed to persist data",
parameters: params
)
end
redirect_to root_path
end
end
我们从外部系统(其中用户填写了一些数据和帐户创建一个临时的属性集)获得的回调。
让我们假设我们想在回调给我们之后在本地保存一些数据。在这些数据被保存后,我们要拨打外部系统来完成帐户创建过程。外部系统应该返回一个结果,告诉我们成功的一些额外的数据,我们需要坚持本地。我们也知道,在某些例外的情况下,远程系统上的持久性将不会成功发生(让我们说系统不可用,或者在它们的末端出现问题)。
目标是捕获外部持久性异常以及成功并相应采取行动。在成功的情况下,一切都很棒:附加数据存储在本地,发生redirect_to root_path
。但是,在例外的情况下,我们希望向用户指出这一点(可能会将flash[:alert]
设置为在视图中显示)。
我们曾试图用ActiveRecord::Callbacks
从模型after_save
和after_commit
抛出一个异常,并通过设置警报,并可能通过异常的一些异常通知系统(如空中刹车)处理该异常的控制器。在after_save
的情况下,模型抛出异常并由控制器捕获,但记录不保存(即使在外部系统出现异常的情况下,我们也需要保存部分数据 - 这不是上可接受的)。在after_commit
的情况下,控制器抛出并拾取的例外是而不是,但部分记录仍然存在。这意味着我们不能通知用户该异常(除非我们实施一些通知推送机制 - 这是过度杀伤)。
事实证明,我们可以在模型上设置错误after_save
,这很好。但是,这是一个好的一般模式来处理这种情况?
这似乎像它可能是一个非常有用的资源... http://rubysource.com/ddd-for-rails-developers-part-1-layered-architecture/ 通过现在读。 另外: http://railsconf2012.com/sessions/50 – zealoushacker