Rails 3 事务,回滚一切

发布于 2024-11-15 06:27:37 字数 1095 浏览 1 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

没有心的人 2024-11-22 06:27:37

看来我要做的就是手动引发 ActiveRecord::Rollback,否则它将无法按预期工作。 ActiveRecord::Rollback 是唯一不会导致屏幕转储的方法。 http://api.rubyonrails.org/classes/ActiveRecord/Rollback.html

它会像这样工作是有道理的,但实际上并不是我直观地认为它会如何工作。如果我错了,请纠正我。

所以新代码看起来像这样:

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
                 @_errors = true
                 render "new_chores"
            end
            raise ActiveRecord::Rollback if @_errors
        end
    end
end

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:

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
                 @_errors = true
                 render "new_chores"
            end
            raise ActiveRecord::Rollback if @_errors
        end
    end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文