2010-05-30 8 views
5

Ich habe ein ActiveRecord-Modellobjekt Foo; es stellt eine Standarddatenbankzeile dar.ActiveRecord save() für eine Instanz verhindern

Ich möchte in der Lage sein, modifizierte Versionen von Instanzen dieses Objekts anzuzeigen. Ich möchte die Klasse selbst wiederverwenden, da sie bereits alle Haken & Aspekte hat, die ich brauche. (Zum Beispiel: Ich habe bereits eine Ansicht, die die entsprechenden Attribute anzeigt). Grundsätzlich möchte ich die Modellinstanz klonen, einige ihrer Eigenschaften ändern und sie dem Aufrufer zurückgeben (Ansicht, Test, usw.).

Ich mache nicht wollen diese Attributänderungen zurück in die Datenbank. Allerdings möchte ich das Attribut id in die geklonte Version einbeziehen, da es den Umgang mit den Route-Helfern viel einfacher macht. Daher plane ich, ActiveRecord::Base.clone() aufzurufen, die ID der geklonten Instanz manuell festzulegen und dann die entsprechenden Attributänderungen an der neuen Instanz vorzunehmen. Das hat mich aber beunruhigt; eine save() auf der modifizierten Instanz und meine ursprünglichen Daten werden verprügelt werden.

Also, ich bin auf der Suche nach der neuen Instanz zu sperren, damit es nichts anderes tut. Ich plane bereits, freeze() zu benennen (unter der Voraussetzung, dass dies weitere Änderungen am Objekt verhindert, obwohl die documentation isn't terribly clear). Ich sehe jedoch keinen offensichtlichen Weg, um ein Speichern zu verhindern().

Was wäre der beste Ansatz, um dies zu erreichen?

+1

Wenn Sie mit dem Standard Active Objekt um diese deutlich Schlamassel benötigen erhöhen können, gibt es wahrscheinlich einen besseren Weg, um das Problem zu nähern. – Matchu

+0

Ich bin sicherlich offen für Alternativen –

Antwort

4

Es gibt möglicherweise eine idiomatische Möglichkeit, dies zu tun, aber eine Möglichkeit wäre, ein virtuelles Attribut zu setzen und es in einem before_save Callback zu überprüfen. Wenn Sie das Objekt klonen, legen Sie das virtuelle Attribut fest - etwa is_clone bis true. Definieren Sie dann einen before_save Callback für Ihre Modellklasse, der das Speichern verhindert, wenn dieses Attribut festgelegt ist.

4

freeze() scheint zu erreichen, was ich will, obwohl auf eine hässliche Art und Weise.

x = Factory.create(:my_model) 
x.save! # true 
x.freeze 
x.save! 
TypeError: can't modify frozen hash 

Ich vermute, dass save() versucht, die erstellt/geändert Attribute zu aktualisieren, die fehlschlägt, weil die Attribute Hash gefroren ist.

Also, Einfrieren wird das Speichern verhindern ... aber ich würde eine zuverlässigere Methode mit einer spezifischeren Fehlermeldung schätzen.

+2

Nur um zu klären, wird einfrieren verhindern, dass die Instanz überhaupt geändert wird, während readonly! erlaubt Modifikationen, aber verhindert, dass die modifizierte Instanz in der Datenbank gespeichert wird. –

+0

Danke für das Update @DavidAldridge; Ich habe meine angenommene Antwort geändert. –

Verwandte Themen