Rails 3:a​​fter_create的回滚

我有一份报名表。

当用户注册时,应用程序应该将数据保存在enrollmentsusers表中。 (我需要这种分离,因为用户的个人资料可以更改,但他为该特定注册输入的数据必须存档。因此,即使稍后用户更改了他的姓氏,我也会在注册表单中获得他的初始信息。)

所以我在考虑在注册表中保存数据,然后进行after_create调用,就像这样……

 class Enrollment < ActiveRecord::Base after_create :save_corresponding_user def save_corresponding_user user = User.new user.full_name = self.user_full_name user.email = self.user_email user.mobile_phone = self.user_mobile_phone user.save end end 

问题是,如果因任何原因保存用户失败该怎么办? 如何从注册表中回滚和销毁刚刚保存的数据?

after_create是保存当前模型的事务的一部分。 因此,如果您的代码崩溃或者after_create返回false,它应该回滚当前事务并使enrollment保存无效。

如果你想模拟它,将它添加到你的after_create中,看看是否一切都按预期工作:

 raise Exception.new("CRASH") 

after_create返回falseafter_create

整个回调链包含在一个事务中。 如果在回调方法之前返回任何错误或引发exception,则执行链将暂停并发出ROLLBACK; 回调之后只能通过引发exception来实现。

此外,您必须raise ActiveRecord::Rollback

在回调链暂停后,Rails将重新引发任何非ActiveRecord :: Rollbackexception。 引发除ActiveRecord :: Rollback之外的exception可能会破坏不期望save和update_attributes(通常尝试返回true或false)等方法引发exception的代码。

http://guides.rubyonrails.org/active_record_callbacks.html#halting-execution

我做这样的事情:

 after_create do if condition errors.add(:attr, 'Blah blah blah.') raise ActiveRecord::Rollback end end 

对于Rails 3: http : //guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#halting-execution

正如@anthonyalberto所提到的,after_create已经是交易的一部分。 要定义事务,您可以在控制器中使用以下内容:

 Enrollment.transaction do @enrollment.save! end 

这真的是你需要做的,如果注册保存失败或者用户保存失败,它将回滚整个事务。 以下是更多信息: http : //api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html