接下来的另一个问题(Rails controller - execute action only if the two methods inside succeed (mutually dependent methods)),我想确保在我的控制器的一个动作中,如果用户没有看到消息由Rails UJS方法显示,那么控制器操作的第一个方法也不会被执行。Rails控制器 - 只有Rails UJS方法成功时才执行动作(相互依赖的方法)
背景
我有一个名为 '动作' 方法的控制器。当应用进入方法'example_action'时,它实现第一个方法(1)update_user_table,然后(2)另一个update_userdeal_table。 (都将读取和写入数据库),然后(3)与Rails UJS(ajax)调用相关的第三种方法。
我的问题如下:在控制器中间超时的情况下,我想避免用户表(通过方法1)更新,UserDeal表更新(通过方法2)的情况,但不是第三方法,即显示消息FAILS(错误,超时,状态如500或404或取消或超时...)的ajax请求。
在我的应用程序,对移动用户,如果他们在与互联网连接的地铁,它们启动,通过“example_action”控制器进入请求,成功地执行第一方法(1)和第二方法(2),但是然后他们以非常低的(< 5b/sec)或者没有互联网连接进入隧道60秒,所以出于UX的原因,我超时了请求并向用户显示,对不起花了太长时间,请重试。问题是,如果我不能向他们展示结果(3),我需要能够不执行(1)和(2)。我需要两个方法(1)和(2)和(3)“相互依赖”:如果一个不成功,另一个不应该被执行。这是我能描述它的最好方式。
今天这是我的代码。它不起作用,因为我通过点击手动进行测试,然后在2秒钟后断开互联网连接。我在我的数据库中看到(1)和(2)已执行且数据库已更新,但我看到消息'抱歉花了太长时间,请重试'。
这是正确的做法吗?如果是的话,该怎么做? 如果不是,我应该尝试一个不同的角度,如:如果(1)和(2)是成功的,但不是(3)我是否应该存储事实的轨道UJS xhr状态是一个错误或超时,因此模式wxas没有有效显示给用户,然后在他们恢复在线时向他们显示结果/消息?
下面是代码
html页面为用户 上的按钮的用户点击触发一个Rails UJS aajax请求将显示最终模式消息
<div id=zone">
<%= link_to image_tag(smallest_src_request),
deal_modal_path,
remote: true %>
</div>
此发送到指向此控制器动作的路线
交易控制器
class DealsController < ApplicationController
def deal_modal
Deal.transaction do
update_user_table # that's the (1)
update_userdeal_table # that's the (2)
# show_modal_message
respond_to do |format|
format.js
end
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
这指向一个js.erb视图文件
deal_modal.js。ERB
showModalMessage("Here is your result <variable and all>);
因为AJAX,错误,超时...(如有必要,这个问题的解决),我使用的Rails UJS设置。
重要:正是在这里,在错误或超时的情况下,我送自带代替你通常得到的错误/超时模式消息(见上方“这是你的结果。”)
$(document).on('page:change', function() {
$("#zone").
on('ajax:error',function(event,xhr, status, error){
console.log(' ajax call failed:', error);
var msg;
msg = Messenger().post({
hideAfter: 4,
message: "sorry it took too long, try again."
});
});
$(document).on('page:change', function() {
//set timeout Rails UJS ajax option that will display message for ajax:error cases defined above
$.rails.ajax = function(options) {
if (!options.timeout) {
options.timeout = 5000;
}
return $.ajax(options);
};
});
我会尝试,但我不知道事务是否“习惯”/实际上可以捕获“非红宝石”错误。即如果轨道UJS抛出错误,如状态'超时'或'错误'(这不是真正的红宝石生态系统,但更多的JavaScript的事情),交易将它分类为失败,并移动到块救援@成功=假? – Mathieu
我认为你的建议很酷,但不符合我的要求,或者我可能会误解你的建议:我的目标是,如果导轨UJS(通过respond_to format.js)超时,则会回滚两个第一个方法update_user_table和_updateuserdeal_table。从某种意义上说,它就像上一个问题:我想要这三种方法“联合在一起”:如果第三种方法失败,那么我不希望2先执行(或者至少我希望它们回滚) – Mathieu
我的当前代码已经使我能够向他们展示错误消息('抱歉太久了,再次尝试'当它超时时:这已经起作用了。什么都行不通,即使它向他们显示Rails UJS错误消息('对不起太久了。 ..'),update_user和update_userdeal不会被回滚,数据库的更新也不会被取消 – Mathieu