Rails controller - 只有在 Rails UJS 方法成功时才执行动作(相互依赖的方法)
Rails controller - execute action only if the a Rails UJS method inside succeed (mutually dependent methods)
在另一个问题 () 之后,我想确保在我的控制器的一个操作中,如果用户没有看到 Rails UJS 方法显示的消息,那么控制器操作的第一个方法也未实现。
上下文
我有一个控制器,其方法名为 'actions'。当应用进入方法 'example_action' 内部时,它会实现第一个方法 (1) update_user_table,然后 (2) 另一个 update_userdeal_table。 (两者都将读取和写入数据库)然后 (3) 与 Rails UJS(ajax) 调用相关的第三种方法。
我的问题如下:在控制器中间超时的情况下,我想避免更新 User table(通过方法 1),UserDeal table 已更新(通过方法 2)但不是第三种方法,即显示消息失败的 ajax 请求(错误、超时、...状态如 500 或 404 或已取消或超时...)。
在我的应用程序中,对于移动用户,如果他们在有互联网连接的地铁中,他们会启动通过 'example_action' 控制器的请求,成功执行第一种方法 (1) 和第二种方法 (2) ) 但随后他们以非常非常低(<5b/秒)或无互联网连接进入隧道 60 秒,因此出于 UX 原因,我将请求超时并显示给用户 'sorry it took too long, try again'。问题是,如果我不能向他们显示结果 (3),我需要能够不执行 (1) 和 (2)。
我需要(1)和(2)和(3)这两个方法"mutually dependent":如果一个不成功,另一个就不要执行了。这是我能描述的最好的方式。
今天这是我的代码。它不起作用,因为我通过单击进行手动测试,然后仅 2 秒后我断开了互联网连接。我在我的数据库中看到执行了 (1) 和 (2) 并且数据库已更新,但我看到消息 'sorry it took too long, try again'.
这是正确的做法吗?如果是,该怎么做?
如果不是,我是否应该尝试不同的角度,例如:如果 (1) 和 (2) 成功但不成功 (3) 我是否应该存储 rails UJS xhr 状态是错误或超时的事实,因此模态wxas 没有有效地显示给用户,然后在他们重新上线后向他们显示 result/message?
这是代码
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 设置。
重要提示: 在这里,如果出现错误或超时,我会发送错误/超时模式消息来代替您通常收到的消息(见上文) "Here is your result..")
$(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);
};
});
所以事务只有在抛出错误时才会回滚。如果抛出未处理的错误,您的应用程序将崩溃并以某种方式显示 500 错误。
为了向用户显示响应,无论是成功还是错误,您都需要渲染一些东西。所以你不想阻止 respond_to
块的执行。处理此问题的一种方法是通过实例变量设置标志。
def deal_modal
begin
Deal.transaction do
update_user_table
update_userdeal_table
end
@success = true
rescue
@success = false
end
# show_modal_message
respond_to do |format|
format.js
end
end
然后在deal_modal.js.erb
<% if @success %>
showModalMessage("Here is your result <variable and all>");
<% else %>
showModalMessage("There was a problem");
<% end %>
编辑:
处理连接问题确实很棘手,而且没有真正理想的解决方案。我通常会让数据库不间断地继续运行,并让它 return 根据自己的时间决定成功或失败。对于冗长的事务,您可以使用 gem 之类的 delayed_job or sidekiq 在后台处理操作,并让 rails 控制器 return 响应“...待处理.. 。“ 或者其他的东西。除非你在前端使用 websockets,否则这意味着不断地用 ajax 请求轮询服务器以查看后台进程是否完成。
在另一个问题 (
上下文
我有一个控制器,其方法名为 'actions'。当应用进入方法 'example_action' 内部时,它会实现第一个方法 (1) update_user_table,然后 (2) 另一个 update_userdeal_table。 (两者都将读取和写入数据库)然后 (3) 与 Rails UJS(ajax) 调用相关的第三种方法。
我的问题如下:在控制器中间超时的情况下,我想避免更新 User table(通过方法 1),UserDeal table 已更新(通过方法 2)但不是第三种方法,即显示消息失败的 ajax 请求(错误、超时、...状态如 500 或 404 或已取消或超时...)。
在我的应用程序中,对于移动用户,如果他们在有互联网连接的地铁中,他们会启动通过 'example_action' 控制器的请求,成功执行第一种方法 (1) 和第二种方法 (2) ) 但随后他们以非常非常低(<5b/秒)或无互联网连接进入隧道 60 秒,因此出于 UX 原因,我将请求超时并显示给用户 'sorry it took too long, try again'。问题是,如果我不能向他们显示结果 (3),我需要能够不执行 (1) 和 (2)。
我需要(1)和(2)和(3)这两个方法"mutually dependent":如果一个不成功,另一个就不要执行了。这是我能描述的最好的方式。
今天这是我的代码。它不起作用,因为我通过单击进行手动测试,然后仅 2 秒后我断开了互联网连接。我在我的数据库中看到执行了 (1) 和 (2) 并且数据库已更新,但我看到消息 'sorry it took too long, try again'.
这是正确的做法吗?如果是,该怎么做? 如果不是,我是否应该尝试不同的角度,例如:如果 (1) 和 (2) 成功但不成功 (3) 我是否应该存储 rails UJS xhr 状态是错误或超时的事实,因此模态wxas 没有有效地显示给用户,然后在他们重新上线后向他们显示 result/message?
这是代码
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 设置。
重要提示: 在这里,如果出现错误或超时,我会发送错误/超时模式消息来代替您通常收到的消息(见上文) "Here is your result..")
$(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);
};
});
所以事务只有在抛出错误时才会回滚。如果抛出未处理的错误,您的应用程序将崩溃并以某种方式显示 500 错误。
为了向用户显示响应,无论是成功还是错误,您都需要渲染一些东西。所以你不想阻止 respond_to
块的执行。处理此问题的一种方法是通过实例变量设置标志。
def deal_modal
begin
Deal.transaction do
update_user_table
update_userdeal_table
end
@success = true
rescue
@success = false
end
# show_modal_message
respond_to do |format|
format.js
end
end
然后在deal_modal.js.erb
<% if @success %>
showModalMessage("Here is your result <variable and all>");
<% else %>
showModalMessage("There was a problem");
<% end %>
编辑:
处理连接问题确实很棘手,而且没有真正理想的解决方案。我通常会让数据库不间断地继续运行,并让它 return 根据自己的时间决定成功或失败。对于冗长的事务,您可以使用 gem 之类的 delayed_job or sidekiq 在后台处理操作,并让 rails 控制器 return 响应“...待处理.. 。“ 或者其他的东西。除非你在前端使用 websockets,否则这意味着不断地用 ajax 请求轮询服务器以查看后台进程是否完成。