Rails 3 事务,回滚一切
class Bear < ActiveRecord::Base
def feed!
self.transaction do
raise Exception unless self.foods_eaten << Food.new(:name => "fish")
self.fed_at = Time.now
save!
end
end
end
class Hippo < ActiveRecord::Base
def wash!
self.transaction do
@soap.inventory -= 1
@soap.save!
self.washed_at = Time.now
save!
end
end
end
class ZookeeperController < ApplicationController
def chores
@zookeeper = Zookeeper.find(params[:id])
Animal.transaction do
begin
@hippo.wash!
@bear.feed! # => FAIL AT THIS LINE
@zookeeper.finished_at = Time.now
@zookeeper.save!
redirect_to chores_completed_path
rescue Exception => e
render "new_chores"
end
end
end
end
如果 Zookeeper#chores
被调用并且 @bear.feed!
失败并引发异常,那么一切都会回滚吗?
也欢迎任何有关如何改进此代码的其他建议。
class Bear < ActiveRecord::Base
def feed!
self.transaction do
raise Exception unless self.foods_eaten << Food.new(:name => "fish")
self.fed_at = Time.now
save!
end
end
end
class Hippo < ActiveRecord::Base
def wash!
self.transaction do
@soap.inventory -= 1
@soap.save!
self.washed_at = Time.now
save!
end
end
end
class ZookeeperController < ApplicationController
def chores
@zookeeper = Zookeeper.find(params[:id])
Animal.transaction do
begin
@hippo.wash!
@bear.feed! # => FAIL AT THIS LINE
@zookeeper.finished_at = Time.now
@zookeeper.save!
redirect_to chores_completed_path
rescue Exception => e
render "new_chores"
end
end
end
end
If Zookeeper#chores
gets invoked and @bear.feed!
fails and raises an exception, then will everything rollback?
Any other suggestions on how to improve this code are also welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来我要做的就是手动引发 ActiveRecord::Rollback,否则它将无法按预期工作。 ActiveRecord::Rollback 是唯一不会导致屏幕转储的方法。 http://api.rubyonrails.org/classes/ActiveRecord/Rollback.html
它会像这样工作是有道理的,但实际上并不是我直观地认为它会如何工作。如果我错了,请纠正我。
所以新代码看起来像这样:
It seems like what I have to do is raise an ActiveRecord::Rollback manually, otherwise it won't work as expected. ActiveRecord::Rollback is the only one that won't cause your screen to dump. http://api.rubyonrails.org/classes/ActiveRecord/Rollback.html
It makes sense that it would work like this, but wasn't really how I intuitively thought it would work. Please correct me if I'm wrong.
So the new code would look something like this: