2016-06-08 4 views
1

Ich habe ein Rails UJS modal. Klickt der Benutzer auf die Schaltfläche, wird ein Ajax-Anruf ausgelöst. Ich aktualisiere bestimmte Datenbank, aber ich will, dass, wenn die Schienen ujs/ajax Timeouts aufrufen oder einen Fehler ausgeben, diese Datenbanken NICHT zu aktualisieren.Datenbankaktion verhindern, wenn Rails UJS (Ajax) einen Fehler oder Timeout zurückgibt

Ich glaube, ich muss dies in der Steuerung tun, aber ich finde nicht, wie.

HTML

<div id="zone" class="has-js">  
     <%= link_to image_tag(smallest_src_request), 
       deal_modal_path, 
       remote: true, 
       class: "deal", 
       alt: "loadin'" %> 
     </span> 
    </div> 
    <% end %> 
</div> 

-Controller

def deal_modal  
    # First Find UserDeal participation and update it 
    find_and_update_selected_userdeal 
    # Actions on User 
    update_user_profile 

    respond_to do |format| 
     format.js 
    end 
end 

Also, wenn die Anfrage Timeouts, zeige ich eine klassische Nachricht wie 'Es tut uns leid zu lang ...' was in Ordnung ist, aber ich bemerkte, Trotzdem habe ich tatsächlich alle Controller-Aktionen ausgeführt und die Swerde- und Benutzertabellen aktualisiert.

Ich möchte nicht zu.

Könnte ich ein Vorher oder Nachher-Filter verwenden und sagen, wenn XHR-Status Fehler ist (ich denke, es beinhaltet den Fall von "Timeout"), dann nicht alle diese Methoden innerhalb DealModal-Methode wie find_and_update_selected_userdeal und update_user_profile?

Ist das möglich?

EDIT

einige Kontext

Dieses Problem nicht auf die Effizienz der Datenbank-Aufruf verwandt ist. Eigentlich ist es sehr schnell (bei einer normalen Verbindung sind es 150ms), aber die App ist mobilintensiv und hat einige "Geschäftsregeln" (insbesondere die Zeit, die der Benutzer den Inhalt des Modals sehen kann, nachdem er auf den Knopf geklickt hat.) ist auf 3 beschränkt).

Zum Beispiel: Der Benutzer ist in einer U-Bahn (und im Moment hat er eine Internetverbindung). Er klickt auf den Link, der heute die Tabelle User mit user.total_nb_clicks (Inkrement 1) aktualisiert, aber dann betritt er für 20 sec einen Tunnel mit fast keiner Internetverbindung. Ich habe in meiner App ein UJS-Timeout von 10 Sekunden für UX-Gründe gesetzt (damit die Benutzer es nicht für einen Fehler halten). Die Verbindung ist also so langsam, dass die Nachricht in der Modal via Rails UJS nicht das Ergebnis ist, sondern wie 'sorry timeout, try again'. Aber er darf sein Glück nur dreimal versuchen, also hätte ich seine Kolumne "total_shots" nicht aktualisieren sollen. Es ist weder seine Schuld noch die Schuld der App, es gab einen Tunnel, in dem er nur 5kb/sec Internetverbindung hat: Er sollte immer noch das Recht haben, 2 weitere Modals/Ergebnisse zu sehen. Es ist eine Frage von echten mobilen Usecase, die passieren können ...

+0

Ich würde argumentieren, dass Ihr Ajax-Aufruf abläuft, weil das Datenbank-Update zu lange dauert. Die einzige Möglichkeit, die Datenbank nicht zu aktualisieren, wenn eine Zeitüberschreitung auftritt, wäre, rechtzeitig zurück zu reisen und zu verhindern, dass die Anforderung überhaupt auf die Anwendung trifft. Vielleicht sollten Sie sich darauf konzentrieren, Timeout-Situationen zu vermeiden. Untersuchen Sie, warum Ihre Updates so langsam sind, dass sie zu einem Timeout führen. – spickermann

+0

Ich verstehe, aber nein. Meine App ist mobilintensiv. Zum Beispiel: Der Benutzer ist in einer U-Bahn (und im Moment hat er eine Internetverbindung). Er klickt auf den Link, der heute die Tabelle User mit user.total_nb_clicks (Inkrement 1) aktualisiert, aber dann betritt er für 20 sec einen Tunnel mit fast keiner Internetverbindung. Ich habe in meiner App eine Zeitüberschreitung von 10 Sekunden für UX-Gründe gesetzt (damit die Benutzer es nicht für einen Fehler halten). Dann ist die Nachricht, die er sieht, 'sorry timeout, try again'. Aber er darf nur 3 mal klicken, also hätte ich seine Spalte 'total_shots' nicht aktualisieren sollen. es ist ein Fall im wirklichen Leben. – Mathieu

+0

Fügen Sie dies der Frage hinzu, da dieser Kontext nützlich ist, um die Frage zu verstehen. – Mathieu

Antwort

1

Ich sah ein ähnliches Problem auf how Heroku suggests you handle timeout in its environment, aber ich denke nicht, dass es für Ihr Fall Szenario funktioniert, weil Ihr Timeout nichts mit lang laufenden Server zu tun hat Seitenverarbeitung.

Wenn Ihr Controller seinen Job beendet hat, gibt es keine Möglichkeit zu wissen, ob die HTTP-Anfrage erfolgreich war oder nicht, wenn der Client die Antwort nach der Anfrage nicht erhalten hat. Ich glaube es liegt an der HTTP Protocol is stateless.

Das gesagt, Sie könnten andere Ansätze versuchen. Je einfacher ich mir das vorstellen kann, desto mehr Informationen bleiben erhalten, um dem Benutzer die gleichen Daten zu zeigen, wenn er das nächste Mal versucht, den Inhalt zu visualisieren oder wenn die Verbindung wiederhergestellt wird (nicht als neuer Klick gezählt).

+0

danke. hey, ich benutze auch heroku so sehr interessant, um jetzt die zusätzliche Ebene der Komplexität zu behandeln, die von heroku induziert wird :) aber in Bezug auf meine Frage habe ich am Ende eine Rails-Transaktion benutzt, aber habe noch nicht alles herausgefunden: überprüfe auch meine Kommentare wenn interessiert: http://stackoverflow.com/questions/37729964/rails-controller-execute-action-only-i-f-the-a-rails-ujs-method-inside-succeed – Mathieu

+0

Ich glaube immer noch nicht, dass Sie tun können was hast du gefragt wie du willst. Die verknüpfte Frage in Ihrem Kommentar adressiert auch eine Situation, die aus dem Inneren der Steuerung gerettet wird (z. B. lang andauernder Prozess oder fehlgeschlagene Operation), und eine langsame Antwort, die zurück zu dem Client unterbrochen wurde, ist bereits von der Steuerung weggekommen. Aber wenn Sie Ihr Problem irgendwie gelöst haben, würde ich es auch gerne lernen. Bitte teilen Sie Ihre Lösung! –

+0

Eigentlich habe ich keine Lösung für das Problem gefunden. Ich habe einen Weg gefunden, um dieses Problem und eine für den Augenblick "gut genug" Lösung zu umgehen. Bei den ersten beiden Methoden schließe ich sie in eine Rails-Transaktion ein (wenn also einer von ihnen nicht erstellt wird, wird der andere zurückgesetzt). Aber ich habe immer noch das Problem mit der dritten Methode der Anzeige des modalen (der Antwort format.js Teil). Hier keine Lösung, sondern eine Möglichkeit, das Problem zu umgehen: Wenn die Datenbanken aktualisiert werden, triggere ich mit sidekiq eine E-Mail und ich zeige dem Benutzer die Meldung 'sorry timeout, aber überprüfe deine E-Mail, um das Ergebnis zu sehen. – Mathieu