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.
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: