2010-05-30 77 views
5

我有一個ActiveRecord模型對象Foo;它代表一個標準的數據庫行。在實例上防止ActiveRecord保存()

我希望能夠顯示此對象的實例的修改版本。我想重用這個類,因爲它已經有了我需要的所有方面。 (例如:我已經有一個顯示適當屬性的視圖)。基本上我想克隆模型實例,修改它的一些屬性,並將其反饋給調用者(視圖,測試等)。

我做不是希望這些屬性修改回到數據庫中。不過,我確實希望在克隆版本中包含id屬性,因爲它可以更輕鬆地處理路由助手。因此,我打算調用ActiveRecord::Base.clone(),手動設置克隆實例的ID,然後對新實例進行適當的屬性更改。雖然這讓我擔心;一個save()在修改的實例上,我的原始數據將會被破壞。

所以,我想鎖定新的實例,以便它不會傷害其他任何東西。我已經打算打電話給freeze()(理解這可以防止進一步修改對象,但是documentation isn't terribly clear)。但是,我沒有看到任何明顯的方法來阻止save()。

實現此目標的最佳方法是什麼?

+1

如果您需要周圍的顯著亂用標準的ActiveRecord對象,有可能接近問題的更好的方法。 – Matchu 2010-05-30 00:05:10

+0

我當然願意替代 – 2010-05-30 00:44:06

回答

4

可能有一種更習慣的方式來做到這一點,但一種方法是設置一個虛擬屬性,並在before_save回調中檢查它。在克隆對象時,請設置虛擬屬性 - 可能類似於is_clonetrue。然後爲您的模型類定義一個before_save回調,如果設置了該屬性,則會阻止保存。

4

freeze()似乎正在實現我想要的,儘管以一種難看的方式。

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

我在猜測save()試圖更新創建/修改的屬性,因爲屬性哈希被凍結而失敗。

所以,凍結會阻止儲蓄...但我會很感激更具體的錯誤信息更可靠的方法。

+2

只是澄清一下,凍結將阻止實例被修改,而只讀!將允許修改,但會阻止將修改的實例保存到數據庫。 – 2015-09-09 08:31:24

+0

感謝您的更新@DavidAldridge;我改變了我接受的答案。 – 2015-09-10 13:27:29