我以前做過類似的事情,但只有一層深度關聯。例如。帳戶其中有一個或一對多的地址,聯繫人等。
你應該確保你的相關其他型號的關聯是相當簡單的,所以沒有循環或分球
這是可能最好將它保存爲容易與當前版本的模型進行比較的方式。您需要從比較中排除「原始」字段;-)
在第一次保存模型期間,我會對模型進行深度克隆,並將其關聯並將其保存到序列化字段主要模型中的'原創'。
我想我會使用ActiveRecord的serialize
功能,例如:
Class YourMainModel
...
serialize :original # will serialize this ; make this TEXT field in DB
...
end
你想確保字段的數據庫中的數據類型爲文本或字符串,而不是二進制領域! 期間after_save的模型(即後來導致的錯誤!)
然後我會添加一些代碼做這樣的事情:
# do this in the after_save - so the validations have run:
main_model_object.original ||= main_model_object.deep_clone # ||= to do this only once
main_model_object.save(:validate => false) if main_model_object.original_changed? # save if we added the "copy"
可能有其他的方法來掛鉤這一點,但after_save的有驗證運行的優勢。
您需要確保所有關聯的記錄都是在第一次保存時創建的,可能您可能想用nested_forms Gem做一個「怪物形式」。
參見:
https://github.com/moiristo/deep_cloneable(叉爲Rails 3)
https://github.com/openminds/deep_cloning(原項目)
看看其他的Ryan的RailsCasts:
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
希望這有助於
編輯:
退一步講,限制你的數據庫/數據庫的大小轉儲,簡化你的架構和安全,保留了原圖,你可能想將原件存儲在單獨的文檔存儲中,例如你可以使用MongoDB。
如果你並不需要經常訪問的原件,然後在MongoDB中存儲這是一個結構化文檔可能是真的benefical,它會保持你的主應用程序少令人費解。
當您比較記錄時,您會像第一次那樣深度複製修改後的模型,然後通過原始記錄的「id」字段查找MongoDB記錄,然後比較兩者(兩者都很深克隆)。該解決方案的
額外的好處:它會使其難以accidentially修改原來的,因爲它沒有直接連接到SQL數據庫記錄。例如你不能意外做object.original = something
爲什麼你想使所有關係副本? – Tilo