2012-04-07 5 views
3

Ich habe eine Rails-App, die alle Ihre Facebook-Kontakte importiert. Das braucht etwas Zeit. Ich würde gerne eine "Bitte warten" Seite zeigen, während der Import im Hintergrund stattfindet.Schienen "Bitte warten" Seite

Es scheint, dass ich render und redirect_to nicht auf die gleiche Aktion im Controller setzen kann. Wie kann ich das machen?

if @not_first_time 
    Authentication.delay.update_contact_list(current_user) 
else 
    render 'some page telling the user to wait' 
    Authentication.import_contact_list(current_user) 
end 
redirect_to :root_path, :notice => 'Succesfully logged in' 

Wenn es der Benutzer erstmals in der Website ist, möchte ich eine machen „bitte Seite warten“, starten Sie den Import, und sobald seine auf den Stammpfad getan umleiten, wo eine Menge Verarbeitung dieser Daten

passiert, wenn es nicht das erste Mal ist, dann setzen sie den Kontakt Update im Hintergrund (mit dem delayed_jobs Juwel) und gehen sie direkt auf die Homepage

ich die fb_graph gem bin mit den Kontakte zu importieren. Hier ist die Methode

def self.import_contact_list(user) 
    user.facebook.friends.each do |contact| 
    contact_hash = { 'provider' => 'facebook', 'uid' => contact.identifier, 'name' => contact.name, 'image' => contact.picture(size='large') } 
    unless new_contact = Authentication.find_from_hash(contact_hash) 
    ##create the new contact 
    new_contact = Authentication.create_contact_from_hash(contact_hash) 
    end 
    unless relationship = Relationship.find_from_hash(user, new_contact) 
    #create the relationship if it is inexistent 
    relationship = Relationship.create_from_hash(user, new_contact) 
    end 
end 

Ende

bearbeiten

Ich habe die Lösung unten vorgeschlagen, es funktioniert!

Hier ist meine ‚warten Sie, während wir Kontakte importieren‘ Blick von der Aktion „Warten“

<script> 
jQuery(document).ready(function() { 
    $.get("/import_contacts", function(data) { 
    window.location.replace("/") 
    }); 
}); 
</script> 

<% title 'importing your contacts' %> 

<h1>Please wait while we import your contacts</h1> 
<%= image_tag('images/saving.gif') %> 

Dank!

+0

Haben Sie über Ajax gedacht? vielleicht würde dies zu einer viel einfacheren und flüssigeren Lösung führen. – alex

+1

AJAX ist die Lösung für Sie. Sehen Sie sich http://api.jquery.com/jQuery.get/ an, wenn Sie jQuery verwenden. AJAX get in jQuery bietet eine Callback-Funktion, die ausgeführt wird, wenn die Anfrage zurückkehrt (in Ihrem Fall werden die Kontakte importiert). Nachdem die Anfrage zurückgeschickt wurde, können Sie sich die gewünschte Nachricht anzeigen lassen (in Ihrem Fall "Erfolgreich eingeloggt") – mohamagdy

+0

Ich habe an Ajax gedacht. Aber ich importiere mit dem [fb_graph Juwel] (https://github.com/nov/fb_graph), und ich möchte nicht in den Edelstein-Code einbrechen ... siehe bearbeitete Antwort oben – wachichornia

Antwort

1

Eine einzelne Anfrage erhält eine einzige Antwort - Inhalte können nicht gerendert und umgeleitet werden.

Wenn ich Sie wäre, würde ich immer den langwierigen Prozess in verzögerter Arbeit tun - binden Passagier/Einhorn Instanzen ist nie eine gute Idee. Rendern Sie eine "Bitte warten" -Seite, die regelmäßig aktualisiert wird, um zu prüfen, ob der verzögerte Job abgeschlossen wurde (wenn Sie die ID des verzögerten Jobs speichern, können Sie testen, ob sie noch in der DB ist. Wenn der Job abgeschlossen ist, wird er gelöscht). Wenn der Job abgeschlossen ist, umleiten Sie die Ergebnisseite. Sie könnten das periodische Prüfbit auch über Ajax tun.

+0

das war meine ursprüngliche Absicht, aber es stellt sich heraus, dass delayed_job nie beginnt, die Daten zu verarbeiten, während der Server beschäftigt ist, und der Server immer beschäftigt ist. Der Job würde also Stunden (wenn nicht sogar nie) dauern, um tatsächlich ausgeführt zu werden (getestet). Gibt es eine Möglichkeit, dieses Verhalten zu ändern? – wachichornia

+0

Das hört sich nicht nach etwas an, was ich je bei einem verzögerten Job gesehen habe - es hat kein Wissen darüber, was die Anwendungsinstanzen tun –