Nach einer anderen Frage (Rails controller - execute action only if the two methods inside succeed (mutually dependent methods)) möchte ich sicherstellen, dass innerhalb einer der Aktion meines Controllers, wenn der Benutzer die Nachricht nicht sehen Wenn sie von einer Rails UJS-Methode angezeigt werden, sind auch die ersten Methoden der Controller-Aktion nicht implementiert.Rails Controller - Aktion nur ausführen, wenn die Rails UJS-Methode erfolgreich ist (voneinander abhängige Methoden)
CONTEXT
Ich habe einen Regler mit einer Methode 'Aktionen' genannt. Wenn die App in die Methode 'example_action' eintritt, implementiert sie eine erste Methode (1) update_user_table und dann (2) eine weitere update_userdeal_table. (beide lesen und schreiben die Datenbank) und dann (3) eine dritte Methode, die sich auf einen Rails UJS (ajax) -Aufruf bezieht.
Mein Problem ist das folgende: Im Falle eines Timeouts in der Mitte des Controllers möchte ich vermeiden, dass die User-Tabelle (über Methode 1) aktualisiert wird, die UserDeal-Tabelle aber über Methode 2 aktualisiert wird NICHT die dritte Methode, dh die Ajax-Anfrage, die eine Meldung FAILS (Fehler, Timeout, ... Status wie 500 oder 404 oder abgebrochen oder Timeout ...) anzeigt.
In meiner App, für mobile Benutzer, wenn sie in einer U-Bahn mit Internetverbindung sind, starten sie die Anfrage, die durch 'example_action' Controller geht, führt erfolgreich die erste Methode (1) und zweite Methode (2) aber dann sie betreten einen Tunnel für 60 Sekunden mit sehr sehr niedriger (< 5b/sec) oder KEINE Internetverbindung, so dass ich aus UX-Gründen die Anfrage abbringe und dem Benutzer zeige, dass es zu lange gedauert hat, versuche es erneut. Das Problem ist, dass ich, wenn ich ihnen das Ergebnis (3) nicht zeigen konnte, nicht in der Lage sein muss, (1) und (2) auszuführen.
Ich brauche die beiden Methoden (1) und (2) und (3) "voneinander abhängig": Wenn einer nicht gelingt, sollte der andere nicht ausgeführt werden. Es ist der beste Weg, um es zu beschreiben.
Heute Hier ist mein Code. Es funktioniert nicht, da ich manuell durch Klicken versuche und dann nach nur 2 Sekunden die Internetverbindung abbringe. Ich sehe in meiner Datenbank, dass (1) und (2) ausgeführt wurden und die Datenbanken aktualisiert wurden, aber ich sah die Meldung "Entschuldigung, es hat zu lange gedauert, versuche es erneut".
Ist das der richtige Ansatz? Wenn ja, wie? Wenn nicht, sollte ich einen anderen Winkel versuchen wie: Wenn (1) und (2) erfolgreich waren, aber nicht (3) sollte ich die Tatsache speichern, dass die Schienen UJS xhr Status ein Fehler oder Timeout war, dass folglich das modale wxas nicht effektiv dem Benutzer angezeigt werden und ihnen dann das Ergebnis/die Nachricht zeigen, sobald sie wieder online sind? Hier
ist der Code
HTML-Seite für den Benutzer der Benutzer klicken Sie auf eine Schaltfläche, die eine Rails UJS Aajax Anfrage auslöst, die letztlich die modale Meldung angezeigt wird
<div id=zone">
<%= link_to image_tag(smallest_src_request),
deal_modal_path,
remote: true %>
</div>
Dies senden eine Route, die auf diese Controller-Aktion zeigt
Deal-Controller
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
Dies deutet auf eine js.erb Ansicht Datei
deal_modal.js.erb
showModalMessage("Here is your result <variable and all>);
die Ajax, Fehler zu verwalten, Timeouts ... (wenn auf die Auflösung der Frage erforderlich), verwende ich Rails UJS Einstellungen.
WICHTIG: Es ist hier, dass ich im Falle eines Fehlers oder Timeouts die modale Meldung "error/timeout" an die Stelle der sonst üblichen senden (siehe oben "Hier ist Ihr Ergebnis ..")
$(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);
};
});
Ich werde versuchen, aber ich frage mich, ob Transaktionen "verwendet werden"/kann tatsächlich einen "nicht Ruby" Fehler fangen. Dh wenn das Rails UJS einen Fehler wie Status 'timeout' oder 'error' (was nicht wirklich ruby-ocosystem sondern eher eine JavaScript-Sache ist) auslöst, wird die Transaktion es als Fehler klassifizieren und zum Block rescue @ success = false wechseln ? – Mathieu
Ich denke, was Sie vorschlagen, ist cool, aber erfüllt meine Frage nicht oder ich könnte Ihren Vorschlag missverstehen: mein Ziel ist, dass wenn die Rails UJS (via Antwort_to Format.js) Timeouts, dann die beiden ersten Methoden update_user_table und _updateuserdeal_table zurückgerollt werden. In gewissem Sinne ist es wie bei der vorherigen Frage: Ich möchte, dass diese 3 Methoden "zusammenkommen": Wenn der dritte fehlschlägt, dann möchte ich nicht, dass die 2 zuerst ausgeführt wird (oder zumindest möchte ich, dass sie zurückgesetzt werden) – Mathieu
Mein aktueller Code bereits ermöglichen mir, ihnen die Fehlermeldung zu zeigen ("Entschuldigung zu lange, versuche es erneut", wenn es Timeout: das funktioniert bereits. Was nicht funktioniert ist, dass, selbst wenn es ihnen die Rails UJS Fehlermeldung angezeigt wird. .. '), update_user und update_userdeal werden nicht zurückgesetzt und die Updates auf der Datenbank werden nicht "abgebrochen" – Mathieu