Rails 4 - 使用事务和Begin救援块

时间:2017-10-22 23:59:12

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

我有一段代码,用于执行从控制器调用触发的以下操作。我使用Rails Transaction和begin / rescue end block来使下面的代码执行系列更加健壮。它如下所示:

  1. 保存对象
  2. 保存关联并更新属性值
  3. 发送电子邮件
  4. 发送短信
  5. 重定向

    ###in my controller 
     def verify   
        @request=Request.includes(:user).find(params[:id])
        @request.transaction do
          begin
            if @request.accepted?
               ##this method will call 3 more methods in the request model
               @request.send_email_and_sms
               flash[:success] = "Request is moved to another state"
            else
              flash[:error] = "Request was not accepted and couldn't be moved to another state"
            end        
          rescue
            flash[:alert] = "There was some internal error.Kindly debug"
          ensure
            @request.reload
            Rails.logger.info "================Making GO AHEAD TOKEN FALSE AND DEACTIVATE VENUE====================#{@request.attributes}==========="
            redirect_to request_hall_path(@request.user)
          end      
        end    
      end
    

    `

  6. 这是确保每一段代码都执行的正确方法,否则它将使用flash.alert消息进行救援。

    是否还有其他方法可以让这些代码/逻辑变得更加简单和强大?

    提前致谢。

1 个答案:

答案 0 :(得分:0)

我认为你不需要这里的交易阻止。当您拥有“全部或全部”时,您将需要使用交易。需求。一个例子可能是销售产品和创建发票;您不希望在其中一个步骤中使序列失败并且数据库状态不一致(即:不从库存数量中扣除,而是添加到销售中)。

另外,在您的情况下(如上所述),发送电子邮件和短信应该通过作业异步完成,因此它不会阻止当前线程。

无论如何,我认为这样的事情会很好:

 def verify   
   @request = Request.includes(:user).find(params[:id])

   if @request && @request.accepted?
     ##this method will call 3 more methods in the request model
     @request.send_email_and_sms # send async
     flash[:success] = "Request is moved to another state"
   else
     flash[:error] = "Request was not accepted and couldn't be moved to another state"
   end

   redirect_to request_hall_path(@request.user)
end

如果您的#send_email_and_sms有任何数据库写入,那么您可以使用作业挂钩(例如:delayed_job回调)来执行写操作,这样您就可以确定作业已成功完成。因此,请注册回调,以便在成功发送电子邮件和短信后,您可以执行request.update(email_sent: true)

希望有所帮助:)