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

我有一个控制器,其方法称为“动作”。 当应用程序进入方法’example_action’时,它实现第一个方法(1)update_user_table,然后(2)另一个update_userdeal_table。 (都会读写数据库)

我的问题如下: 如果在控制器中间超时,我想避免更新User表(通过方法1)但UserDeal表不是(通过方法2)的情况 。 在我的应用程序中,对于移动用户,如果他们在有地铁连接的地铁中,他们启动通过’example_action’控制器的请求,成功执行第一种方法(1)但是他们进入隧道60秒非常非常低((1)已经执行但未执行(2)。 如果没有更新Userdeal,那么在我的应用程序中更新User表是完全不可能的(它会产生数据一致性问题……)

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

在实践中,因为(1)首先发生,如果(1)失败,则不执行(2)。 完善。

问题是如果(1)成功并且(2)没有执行。 我怎么能对Rails说,如果(2)没有成功执行, 那么我不想执行块’example_action’中的任何内容

那可能吗 ?

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 

如果您使用的是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 

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

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

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

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

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