2012-01-01 14 views
2

私は多くのアイテムを持つプロジェクトを持っています。それは:dependent => :destroyです。 コールバック(特にItemのafter_destroy)を呼び出すときに、アイテムが "単独"で破棄されたが、すべてのプロジェクトが破棄されていない場合にのみ実行するように、レールに伝えようとしています。 プロジェクト全体が破壊されているとき、実際には(アイテムの)after_destroyメソッドを実行する必要はありません。問題があります:依存=>:破棄とインスタンス変数

:dependent => :deleteには、多くの他の関連付けが接続されています(: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を削除し、手動での破壊を扱うですProjectには:dependent => :destroyのアイテムタイプがあり、そのメソッドに移動しなければならないため、これはあまりにも醜いと思われます。

すべてのアイデアは、あなたがプロジェクト全体を削除するときのコールバックを使用する必要がない場合、あなたはDELETE_ALL使う代わりに破壊する可能性が

+0

クラス変数は確かに正しくない、sincすべての*プロジェクトに適用されます。あなたは本当に1つのプロジェクトインスタンスだけを望んでいます... – DGM

+0

DGM - 私は同意します。このクラス変数は間違った選択肢です。 – user198026

答えて

0

をいただければ幸いです。

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

+0

こんにちは、私はItem.rbとの他の多くのhas_many関係を持っているので、これは仕事をしません。 delete_allを実行すると、Itemのリレーションシップなしでアイテムが削除されます。だからItem has_many:papers、:dependent =>:破壊すると、papaersは削除されません – user198026

+0

本当ですか?彼らはカスケードしたと思った。違いはコールバックが実行されるかどうかだけです... – DGM

+1

はい。 delete_allがある場合、ItemsクラスをロードせずにDBから直接削除するだけで、アイテムの関連付けは削除されません。 – user198026

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

こんにちは、ありがとう、これは私が "私が考えることができる他のオプションは、依存関係=>を削除することです:プロジェクトのafter_destroyメソッド内のアイテムの破壊を手動で処理する"私はもっ​​と良い解決策を探しています。ありがとう! – user198026

+0

私はまた本当に気に入っています!! @ destroy_without_statuses_update(シンプルで機能します!) – user198026

+0

@ user198026、 ':dependent =>:destroy'の問題は、親モデルのdestroyコールバックを呼び出す前に関連が破棄されることです。少なくともそれはRails 3.1でどのように起こるかです。なぜ私はあなたのソリューションがまったく機能するのか疑問に思います。 –

関連する問題