【问题标题】:Removing/destroying child object that belongs_to 2 parents删除/销毁属于 2 个父母的子对象
【发布时间】:2013-09-11 11:01:29
【问题描述】:
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 个父母。

如果情节有所不同,则已经失去了情节,但为了完整起见:Concert 和 Artist 在 has_many :through => :engagements 关联中

像 before_save 回调一样在 Concert(和 Artist 中的类比)中添加它:

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

【问题讨论】:

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


    【解决方案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
    

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

    【讨论】:

    • after_remove 不能阻止破坏,before_remove 也不能。除非你在上面设置了accepts_nested_attributes_for :documents, :allow_destroy =&gt; true,否则回调是不可用的。你只能从父模型中停止破坏,document.reload 清除 .marked_for_destruction
    • 从关联中移除不会破坏被移除的对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 2015-06-19
    相关资源
    最近更新 更多