遇到问题:依赖=> :destroy和Instance变量

时间:2012-01-01 13:54:31

标签: ruby-on-rails ruby

我有一个包含很多项目的项目;它是:dependent => :destroy。 我试图在调用回调时告诉rails(特别是Item的after_destroy),仅在项目被“单独”销毁时才运行,但是所有项目都没有被销毁。 当整个项目被销毁时,我实际上根本不需要这个after_destroy方法(Item)。

我不想: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并手动处理Project after_destroy方法中项目的销毁,但它看起来也太丑了,尤其是{{1}有许多项目类型Project必须转移到该方法。

任何想法都将不胜感激

2 个答案:

答案 0 :(得分: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?
    !!@destroy_without_statuses_update
  end
end

答案 1 :(得分:0)

如果在删除整个项目时不需要使用回调,则可以使用delete_all而不是destroy:

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