2017-07-21 121 views
1
class MyTask < ApplicationRecord 
    has_many :jobs, as: :ownerable, dependent: :destroy 
    accepts_nested_attributes_for :jobs, allow_destroy: true 

    before_save :set_some_data 
end 

class Job < ApplicationRecord 
    belongs_to :ownerable, polymorphic: true, optional: true 
end 

在之後進行回調:set_some_data方法,我們實際上採取所有屬於MyTask對象的作業中的值,並執行一些計算,並將結果保存在列(實際上,只是一個self.column_name = calculated_value ,而不是實際調用保存)。破壞孩子只記錄

問題是,列上的UPDATE發生在任何標記爲破壞的作業之前,即params中的"_destroy" => 1。很顯然,它包括來自已刪除作業的數據,這是不正確的。

我目前在做以下 - 改變回調:

after_save :set_some_data 

def set_some_data 
    #Do stuff 
    # WARNING: Don't use any method that will trigger an after_save callback. Infinite loop otherwise. 
    self.update_columns(column_name: calculated_value) 
end 

據我想要做什麼。但這是一個很好的解決方案嗎?你能否提出一些更好的選擇?

回答

1

您可以用after_destroy做到這一點,並把在job.rb這將確保當孩子被刪除(作業),它會調用父更新值

class Job < ApplicationRecord 
    belongs_to :ownerable, polymorphic: true, optional: true 

    after_destroy :update_parent 


    def update_parent 
    # check your parent model 
    self.ownerable.update_columns(column_name: calculated_value) 
    end 
end 

更多細節回調方法你可以檢查this

+0

但是在這種情況下,假設我銷燬了父MyTask對象的3個作業,則此回調將運行3次。它也不會在創建或更新作業時運行,這意味着我仍然需要我的before_save回調。 這對我來說似乎不是很有效。 Upvoted因爲它會完成所需的工作。 – arunt

+0

是的,我與你的情況相同,我使用after_save來創建和更新,它似乎效率不高(是的我同意),尤其是如果在一個父代中有很多作業,但這裏的意思是「保存事務」父母應該直接更新,我打開,也想學習這種情況下,如果有另一種選擇,節省交易和有效,因爲我有這樣的例子很多 – widjajayd