删除/销毁belongs_to 2个父项的子对象

时间:2013-09-07 12:05:35

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord ruby-on-rails-3.2

class Concert < ActiveRecord::Base
    has_many :documents, :uniq => true 
    accepts_nested_attributes_for :documents #???, :allow_destroy => true

class Artist < ActiveRecord::Base
    has_one :document, :validate => true
    accepts_nested_attributes_for :document #???, :allow_destroy => true

class Document < ActiveRecord::Base
    belongs_to :artist  
    belongs_to :concert

我想从音乐会中删除文档:如果它的唯一父级是音乐会,则将其销毁,但将concert_id设置为nil并保存文档,如果它也属于艺术家。 (以及艺术家观点的模拟观点)

我想要:

  • 在艺术家和演唱会班级拦截.marked_for_destruction?如果文档被另一个父项引用,则停止销毁文档。我该怎么做?

甚至更好:

  • 在文档类中添加一个before_destroy回调函数,检查此文档是否有(实时)第二个父项,但后来我需要知道哪个类(父)正在调用destroy,所以我知道要删除哪个外键。我怎么知道哪个父母正在调用destroy?

我已经探索过多态关联,但是我需要SAME文档来归属于2个父母。

如果它有任何不同,已经失去了情节,但为了完整起见:音乐会和艺术家在一个has_many:通过=&gt; :参与协会

在Concert(和Artist中的模拟)中添加此项作为before_save回调有效:

def documents_for_deletion?
  self.documents.each do |doc| 
    if doc.marked_for_destruction?
      unless doc.artist_id.blank?
        doc.reload
        doc.concert_id = nil
      end
    end
  end
end

http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html

有没有办法在Document中作为before_destroy回调来做? (我更喜欢,见上文)

1 个答案:

答案 0 :(得分:1)

您可以使用关联回调,例如after_remove:

class Concert < ActiveRecord::Base
  has_many :documents, :uniq => true, :after_remove => :destroy_document_with_no_parent

def destroy_document_with_no_parent(removed_document)
  removed_document.destroy unless removed_document.concert_id || removed_document.artist_id
end

您可能应该将该方法放在一些帮助器中,这样您就不需要在两个类中重复这些代码了。