1
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 回调,检查该文档是否有(活动的)第二个父级,但是我需要知道哪个类(父级)正在调用销毁,所以我知道要删除哪个外键。我怎么知道哪个父母正在调用销毁?

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

如果有任何区别,就失去了情节,但为了完整起见:音乐会和艺术家在 has_many :through => :engagements 关联中

在 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 回调?(我更喜欢,见上文)

4

1 回答 1

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

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

于 2013-09-07T13:10:00.617 回答