Bevor ich dies als Fehler an das Rails-Team melde, wollte ich sehen, ob ich etwas falsch mache, was dieses Verhalten verursachen könnte. Insbesondere scheint die :autosave-Eigenschaft von has_many-Assoziationen nicht wie in der Dokumentation beschrieben zu funktionieren.
Als Referenz finden Sie hier die aktuellste API-Dokumentation: http://api.rubyonrails.org/classes/Acti ation.html
Schauen Sie sich den Abschnitt "One-to-many-Beispiel" an. Ich habe den Code dort genau in einer Testanwendung dupliziert, und er funktioniert bei mir nicht. Insbesondere wird das übergeordnete Objekt aktualisiert, das untergeordnete Objekt jedoch nicht.
Mein Schema ist wie folgt:
create_table :posts do |t|
t.string :title
t.timestamps
end
create_table :comments do |t|
t.text :body
t.integer :post_id
t.timestamps
Meine Modelle sind wie folgt:
class Post < ActiveRecord::Base
has_many :comments, :autosave => true
end
class Comment < ActiveRecord::Base
belongs_to :post
end
In der Konsole führe ich die folgenden Befehle aus (die Objekte post und comments sind zu diesem Zeitpunkt bereits in der DB):
post = Post.find(1)
post.title # => "The current global position of migrating ducks"
post.comments.first.body # => "Wow, awesome info thanks!"
post.comments.last.body # => "Actually, your article should be named differently."
post.title = "On the migration of ducks"
post.comments.last.body = "Actually, your article should be named differently. [UPDATED]: You are right, thanks."
post.save
post.reload
Aber das ist das, was ich für den Output bekomme:
post.title # => "On the migration of ducks"
post.comments.last.body # => "Actually, your article should be named differently."
Wenn ich mir die Protokolle anschaue, ist dies die einzige Aktualisierungsanweisung, die ich sehe:
Post Update (0.6ms) UPDATE "posts" SET "updated_at" = '2010-01-18 23:32:39', "title" = 'Über die Migration von Enten' WHERE "id" = 1
Es hat also den Anschein, dass die Speicherung nicht bis zum Kommentarobjekt durchgereicht wurde, was mir eindeutig als Fehler erscheint. Ich habe dies auf zwei verschiedenen Systemen mit 2.3.4 versucht und das Verhalten ist wiederholbar.
Aber jetzt kommt das Seltsame: Wenn ich zuerst "post.comments" aufrufe, bevor ich versuche, den Wert zu setzen, funktioniert es einwandfrei! Um genau zu sein:
post.title = "On the migration of ducks"
post.comments #Note that this line was not called above
post.comments.last.body = "Actually, your article should be named differently. [UPDATED]: You are right, thanks."
post.save
post.reload
Jetzt liefert die Ausgabe die richtigen Ergebnisse:
post.title # => "On the migration of ducks"
post.comments.last.body # => "Actually, your article should be named differently. [UPDATED]: You are right, thanks."
Und die Protokolle enthalten die korrekte Aktualisierung:
Comment Update (0.3ms) UPDATE "comments" SET "updated_at" = '2010-01-18 23:44:43', "body" = 'Eigentlich sollte Ihr Artikel anders heißen. [AKTUALISIERT]: Sie haben recht, danke.' WHERE "id" = 2
Das sieht für mich also wirklich nicht gut aus. Ich vermute, dass es ein Problem mit der Art und Weise ist, wie Objektreferenzen gehandhabt werden, d. h. dass das Objekt, sobald es Teil einer zugewiesenen Sammlung ist, gut gespeichert wird, aber nicht, wenn es als einzelnes Objekt aus der Datenbank gezogen wird. Aber bevor ich dies an das Rails-Team als Fehler einreichen, wollte ich sehen, ob jemand anderes in dieses Problem gelaufen war, oder wenn ich nur etwas völlig dumm, dass ich nicht sehen, weil ich den ganzen Tag auf diese verbracht habe.