Rails控制器 - 仅当内部两个方法成功时才执行操作(相互依赖的方法)

时间:2016-06-09 13:39:54

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4

我有一个名为' actions'的控制器。当应用程序进入方法' example_action'时,它实现第一个方法(1)update_user_table,然后(2)另一个update_userdeal_table。 (两者都会读写数据库)

我的问题如下:如果在控制器中间超时,我想避免更新User表(通过方法1)但UserDeal表不是(通过方法2)的情况)即可。在我的应用中,对于移动用户而言,如果他们是在有互联网连接的地铁中,他们就会启动通过&#39; example_action&#39;控制器,成功执行第一种方法(1),但随后他们进入隧道60秒,非常低(<5b /秒)或没有互联网连接,所以出于用户体验的原因,我超时请求并显示给用户& #39;抱歉太久了,再试一次&#39;。 问题是&#34;损坏&#34;已经在数据库中了:) =&gt; (1)已经执行但未执行(2)。如果没有更新Userdeal,那么在我的应用程序中更新User表是完全不可能的(它会产生数据一致性问题......)

我需要两个方法(1)和(2)是相互依赖的&#34;:如果一个不成功,则不应该执行另一个。这是我描述它的最佳方式。

在实践中,由于(1)首先发生,如果(1)失败,则(2)不会被执行。完美。

问题是如果(1)成功并且(2)没有执行。我怎么能对Rails说,如果(2)没有成功执行,那么我不想执行块内的任何事情&#39; example_action&#39; 。< / p>

这可能吗?

class DealsController < ApplicationController
  def example_action
    update_user_table
    update_userdeal_table   
  end

  private
  def update_user_table
    # update the table User so it needs to connect to internet and acces the distant User table
  end
  def update_userdeal_table
    # update the table UserDeal table so it needs to connect to internet and access the distant UserDeal table
  end
end

2 个答案:

答案 0 :(得分:1)

如果您使用ActiveRecord,则可以将方法移至模型中并在transaction块中执行。

class DealsController < ApplicationController
  def example_action
      // 'user' would have to be defined, or you could work with it as a class method in some way
      user.make_the_deal
  end
end

class User < ActiveRecord::Base
  def make_the_deal
    transaction do
      update_user_table
      update_userdeal_table
    end
  end

  def update_user_table
  end

  def update_userdeal_table
  end
end

你不一定要把你的模型放进去做,你可以这样做:

User.transaction do
  update_user_table
  update_userdeal_table
end

在您的控制器中。但建议将交易放入模型中。

答案 1 :(得分:1)

处理此问题的最佳方法是使用交易。您可以继续在控制器本身中使用事务,但通常认为这是不好的做法。

class DealsController < ApplicationController
  def example_action
    Deal.transaction do
      update_user_table
      update_userdeal_table   
    end
  end
end

与其他提到的一样,您可以将方法移动到模型中的常用方法,并使用事务块将其包装。

我找到了关于rails事务的非常好的帖子。 http://markdaggett.com/blog/2011/12/01/transactions-in-rails/