我有一段代码,用于执行从控制器调用触发的以下操作。我使用Rails Transaction和begin / rescue end block来使下面的代码执行系列更加健壮。它如下所示:
重定向
###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
`
这是确保每一段代码都执行的正确方法,否则它将使用flash.alert消息进行救援。
是否还有其他方法可以让这些代码/逻辑变得更加简单和强大?
提前致谢。
答案 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)
希望有所帮助:)