Ruby on Rails: лучший подход для удаления связанных моделей - PullRequest
2 голосов
/ 26 января 2012

У меня определены следующие классы / отношения:

class Component < ActiveRecord::Base
    has_many :component_stories,:dependent => :destroy
    has_many :stories, :through => :component_stories
end

class Story < ActiveRecord:Base
    has_many :component_stories,:dependent => :destroy
    has_many :components, :through => :component_stories
end

class ComponentStory < ActiveRecord::Base
    belongs_to :component
    belongs_to :story
end

Допустим, у нас есть компонент1 с двумя историями: story1 и story2.story2 также принадлежит компоненту2.Если мы удалим component1, story1 будет удален без возможности восстановления, но story2 останется, поскольку он принадлежит компоненту2.Я определил метод в модели компонентов для удаления журналов, не связанных с каким-либо другим компонентом:

def delete_dependent_stories
   stories.each do |story|
     if story.component_stories.size == 1
       story.destroy
     end
   end
end

Этот метод будет вызываться в действии уничтожения для компонентов_контроллера:

def destroy
   component = Component.find(params[:id])
   component.delete_dependent_stories
   component.destroy
   ...
end

ThisКстати, я проверяю, нет ли «зомби» историй, не связанных с каким-либо компонентом.Меня беспокоит, может ли быть лучший подход, который заменит этот метод в модели компонентов.

1 Ответ

0 голосов
/ 29 марта 2012

Вы должны воспользоваться такими моделями обратных вызовов, как это:

class Component < ActiveRecord::Base
  has_many :component_stories,:dependent => :destroy
  has_many :stories, :through => :component_stories

  after_destroy :delete_dependent_story?

  private

  def delete_dependent_stories
    stories.each do |story|
      if story.has_component_stories?
        story.destroy
      end
  end
end

class Story < ActiveRecord:Base
  has_many :component_stories,:dependent => :destroy
  has_many :components, :through => :component_stories

  self.has_component_story?
    component_stories.size == 1
  end
end

Не используйте before_destroy, так как это удалит story независимо от успешности удаления component.

...