2017-05-17 76 views
0

我試圖製作一個users的備份表,名爲archived users。它通過散列當前用戶屬性(self)並在self.id中合併爲user_id來創建ArchivedUser。爲ArchivedUser創建或更新記錄

當用戶恢復時,他們的記錄仍然保留在ArchivedUser表中。如果用戶第二次被刪除,它應該更新任何已更改的屬性。

目前,它拋出一個驗證錯誤: Validation failed: User has already been taken,因爲self.idArchivedUser表已經存在。

什麼是更好的方法來處理更新現有對象的對象(如果可能),或創建新記錄(如果它不存在)。我使用的軌道4,並且試圖find_or_create_by但它拋出一個錯誤

Mysql2::Error: Unknown column 'device_details.device_app_version'

這是奇怪的,因爲該列兩個表中存在並且沒有得到修改。

用戶刪除方法

# creates ArchivedUser with the exact attributes of the User 
    # object and merges self.id to fill user_id on ArchivedUser 
    if ArchivedUser.create!(
    self.attributes.merge(user_id: self.id) 
) 

謝謝你帶吧!

回答

0

如果archived_users表是真正充當用戶備份,並且不添加任何額外的功能,我會溝ArchiveUser模型,只需在User模型添加archived布爾告訴用戶是否被存檔。

這樣你就不必處理移動一個對象到另一個表並掛鉤到一個刪除回調。

但是,如果您的ArchiveUser模型確實提供了與User相比有些不同的功能,另一個選擇是使用single table inheritence來區分用戶類型。在這種情況下,您可以讓User管理所有用戶,然後區分用戶爲例如ActiveUserArchivedUser

這需要更多的設置,如果您還沒有使用STI,可能會有點混淆,但當兩個相似的模型只需略有不同時,它可能會有用。


話雖這麼說,如果你想保持你當前的設置,我相信有我有你的代碼中看到一些問題:

  1. 如果你打算從創建一個對象現有的對象,這是duplicate the object (dup)的良好做法。這樣id將不會自動設置,並可以自動增加。

  2. 如果您確實已從數據庫中刪除User記錄,則沒有理由存儲對其id的引用,因爲它已消失。但是,如果您實際上並沒有刪除記錄,那麼您應該只使用布爾屬性來確定用戶是否處於活動狀態或歸檔狀態。

  3. 我沒有足夠的上下文來說明爲什麼find_or_create_by不工作,但如果是這樣的話,那麼我會盡量保持簡單。不要使用所有的屬性,而只需要一致的(如id),你知道會返回正確的結果。

  4. if ArchivedUser.create! # ...有問題。如果記錄無法創建,則創建後的爆炸(即create!)將引發錯誤,使得if毫無意義。因此,如果您不希望引發錯誤並想要處理未創建記錄的情況,請使用if。如果您確實想要拋出錯誤,請使用create!而不使用if

相關問題