2013-09-29 155 views
0

在我的Rails應用程序中。我有我的基本模型 - 用戶。有很多關聯的對象給用戶。Rails:對象破壞性能

Class User 
has_many :contents, dependent: destroy 
has_many :messages, dependent: destroy 
has_many :ratings, dependent: destroy 
has_many :groups, dependent: destroy 
... 
end 

當我想從我的系統中刪除用戶(銷燬用戶對象)時,大約需要一分鐘才能銷燬所有關聯的對象。處理這種情況的最佳方式是什麼?這在我腦海

一種方法是:

在delayed_job的破壞:

但直到點用戶對象獲取延遲就業摧毀,該用戶不應該爲別人看到。處理這種情況是通過在用戶模型中標記一個標記來刪除,而不是在結果中提取。但是我也使用獅身人面像,並且需要確保這個用戶不會出現獅身人面像結果。

有沒有更好的方法來處理這種情況?

+0

一種選擇是首先銷燬用戶,並將相關對象的銷燬委託給延遲作業。 – tihom

+1

你考慮過使用'delete'而不是'destroy'嗎?http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html – gabrielhilal

+1

@gabrielhilal肯定。但在刪除的情況下,觀察者回調不會發生,我將不得不手動執行它們。就像摧毀用戶會破壞團隊一樣,團隊又必須更新計數並刪除組中的活動。分開處理它們會使代碼變得複雜。但那是這樣嗎? –

回答

0

:依賴

控制會發生什麼,當它的主人被銷燬相關的對象:

:destroy causes the associated object to also be destroyed 
:delete causes the associated object to be deleted directly from the database (so callbacks will not execute) 

刪除會快很多,因爲它只是運行一個數據庫查詢已刪除用戶的每個關聯。

這裏找到更多的選擇:http://guides.rubyonrails.org/association_basics.html#options-for-has-one-dependent

+0

謝謝@八達通保羅。但是我的關聯對象又有它自己的聯繫。像組有很多活動。所以摧毀團體必須摧毀其協會。 –

+0

在這種情況下,您不能使用:刪除:D – cristian

2

的挑戰是,正如你可能已經知道,.destroy方法將加載每個孩子對象,然後調用其.destroy方法。

其中的值是在進行最終銷燬之前對孩子的任何回調進行評估。所以如果一個孩子需要在其他地方清理任何東西,那麼它會這樣做。同樣,如果依賴對象在銷燬方法期間拋出錯誤,則整個銷燬操作將會回滾,並且最終不會導致一些半死對象的跛行。

.delete將銷燬對象而不將它們加載到內存中或執行其回調。然而(顯然)它不會執行回調。

如果你想加快速度,你可以簡單地按照Octopus-Paul的建議做dependent: :delete。這樣可以,但是它不會破壞這些對象的依賴關係,例如,如果組有消息與它們相關聯,或者評級有與它們相關的評論,那麼這些消息都不會被銷燬。

爲了確保所有下游的家屬被摧毀任何必要的回調很榮幸,我認爲你能做的最好是寫一個自定義的before_destroy方法,完成了所有清理,但爲了加快速度使用.delete.delete_all

這會產生遺留問題,因爲有人在下游編寫代碼不一定會預測您的方法,但您可以判斷風險。另一種選擇(如你所說)是使用一個標誌並異步完成這項工作。我可以想象,未來這種風險較少,但今天實施可能會更加昂貴。