2012-01-01 55 views
2

我有一個項目有很多項目;它是:dependent => :destroy。 我在調用回調(特別是Item的after_destroy)時試圖告訴導軌,只有當Item被「單獨」銷燬時才運行,但所有項目都不被銷燬。 當整個項目被銷燬時,我實際上並不需要(項目的)這個after_destroy方法來運行。遇到問題:依賴=>:銷燬和實例變量

我不想做:dependent => :delete,因爲Item中有許多其他關聯連接到它(與:dependent => :destroy)。

它爲我的作品只與類變量,但我希望它曾與一個實例變量工作:

class Project < ActiveRecord::Base 
    has_many :items, :dependent => :destroy 
    before_destroy :destroying_the_project 

    def destroying_the_project 
    # this is a class variable, but I wish I could had @destroying_me 
    # instead of @@destroying_me. 
    @@destroying_me = true 
    end 

    def destroying_the_project? 
    @@destroying_me 
    end 
end 

class Item < ActiveRecord::Base 
    belongs_to :project 
    after_destroy :update_related_statuses 

    def update_related_statuses 
    # I with I could had return if project.destroying_the_project? 
    # but since the callback gets the project from the DB, it's another instance, 
    # so the instance variable is not relevant here 
    return if Project::destroying_the_project? 

    # do a lot of stuff which is IRRELEVANT if the project is being destroyed. 
    # this doesn't work well since if we destroy the project, 
    # we may have already destroyed the suites and the entity 
    suite.delay.suite_update_status 
    entity.delay.update_last_run 
    end 
end 

我能想到的是另一種選擇刪除:dependent => :destroy和手動處理破壞的項目after_destroy方法中的項目,但它似乎也太難看了,特別是因爲Project有許多項目類型:dependent => :destroy必須轉移到該方法。

任何想法,將不勝感激

+0

一個類變量肯定是不正確的,sinc e適用於*所有*項目。你真的只想要一個項目實例... – DGM 2012-01-01 14:48:41

+0

DGM - 我同意。這個類變量絕對是一個不好的選擇。 – user198026 2012-01-01 17:31:11

回答

0

如果您不需要使用刪除整個項目時回調,可以使用DELETE_ALL而不是破壞:

Rails :dependent => :destroy VS :dependent => :delete_all

+0

嗨,這不會做這項工作,因爲我有許多其他has_many關係的Item.rb.如果我將執行delete_all,那麼只需刪除項目,而不使用項目關係。所以如果Item has_many:papers,:dependent =>:destroy,它不會刪除這些文件 – user198026 2012-01-01 15:13:05

+0

你確定嗎?我認爲他們級聯。唯一的區別是回調是否正在運行... – DGM 2012-01-01 15:34:34

+1

是的。如果你有delete_all,它會直接從數據庫中刪除它,而不加載Items類,它不會刪除Items的關聯。 – user198026 2012-01-02 10:04:17

1

我希望這不是最好的解決方案,但至少它的工作原理並沒有通過類變量引入任何全局狀態:

class Project < ActiveRecord::Base 
    has_many :items 
    before_destroy :destroying_the_project 

    def destroying_the_project 
    Rails.logger.info 'Project#destroying_the_project' 
    items.each &:destroy_without_statuses_update 
    end 
end 

class Item < ActiveRecord::Base 
    belongs_to :project 
    after_destroy :update_related_statuses, 
       :unless => :destroy_without_statuses_update? 

    def update_related_statuses 
    Rails.logger.info 'Item#update_related_statuses' 
    end 

    def destroy_without_statuses_update 
    @destroy_without_statuses_update = true 
    destroy 
    end 

    def destroy_without_statuses_update? 
    [email protected]_without_statuses_update 
    end 
end 
+0

嗨,謝謝,這就是我所說的「我可以想到的另一個選擇是刪除:dependent =>:銷燬並手動處理Project after_destroy方法內的項目的銷燬」,所以我知道它會起作用,但我試圖找到更好的解決方案。謝謝! – user198026 2012-01-01 15:15:11

+0

我也非常喜歡!! @ destroy_without_statuses_update(simple and works!) – user198026 2012-01-01 15:18:17

+0

@ user198026,':dependent =>:destroy'的問題是,即使調用父類型之前的任何銷燬回調之前,關聯也會被銷燬。至少這是Rails 3.1上的情況。這讓我想知道爲什麼你的解決方案可以工作。 – 2012-01-01 15:29:21