78 Stimmen

Wie kann ich wissen, wann ich mein Modellobjekt in Rails "aktualisieren" muss?

Hier ist ein Teil eines Integrationstests, den ich gerade durchführe:

user = User.first
assert !user.is_active?

get confirm_email_user_url(user),:confirmId => user.mail_confirmation_hash

assert_equal response.status,200
# because confirm_email_user_url modifies the activation state of the object
user = User.first
assert_equal user.state,"activated"

Ich habe die letzte Stunde damit verbracht, dieses Problem zu beheben :). In meiner anfänglichen Version habe ich nicht reinitialisiert user nachdem auf confirm_email_user_url zugegriffen wurde, und der Status war immer inactive auch wenn der Benutzer aktiviert wurde.

Woher weiß ich, ob ich mein Modellobjekt "neu laden" sollte (in Ermangelung eines besseren Namens)? Was sollte ich dazu aufrufen?

152voto

dantswain Punkte 5297

Sie müssen anrufen user.reload wenn sich die Daten in der Datenbank geändert haben.

In Ihrem obigen Code wird das "user"-Objekt im Speicher aus den Daten erstellt, die aus der Datenbank durch User.first . Dann sieht es so aus, als ob Ihr confirm_email_user_url Datenbank . Das Objekt erfährt davon erst, wenn Sie reload und holt die Daten erneut aus der Datenbank ab.

Ich bin mir nicht sicher, ob es einen programmatischen Weg gibt, um zu wissen, wann das Objekt neu geladen werden muss, aber als Entwickler sollten Sie wissen, was vor sich geht und entsprechend handeln. Meiner Erfahrung nach (die etwas begrenzt ist), ist dies nur ein Problem beim Testen. In der Produktion ist es untypisch, dass ein Objekt in der Datenbank geändert wird, während es im Speicher geladen ist. Normalerweise wird das Objekt im Speicher geändert und dann in der Datenbank gespeichert (d.h., user.email = "foo@bar.com" gefolgt von user.save ). Ich nehme an, dass man bei einer Anwendung mit hoher Aktivität, bei der viele Benutzer in kurzer Folge etwas ändern könnten, vorsichtig sein sollte.

6voto

Thomas Fankhauser Punkte 4919

Btw. dies nicht wirklich funktionieren, wenn Sie Dinge auf das Modell selbst wie tun Report.count . Nach endlosen Versuchen, die Spalteninformationen zurückzusetzen oder eine Instanz des ersten/letzten Datensatzes zu erhalten und neu zu laden, war das Einzige, was mir half, die Verbindung zur Datenbank zwischen den Zählungen wie folgt wiederherzustellen:

initial_count = Report.count

# do something, like invoking a rake task that imports the reports, ..

Report.connection.reconnect!
final_count = Report.count

Dies funktionierte für Rails 2.3.8+, ich weiß nicht, über die 3+ Versionen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X