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?また、ドキュメントが他の親によって参照されている場合は、ドキュメントの破棄を停止します。それ、どうやったら出来るの?

またはさらに良い:

  • このドキュメントに (ライブ) 2 番目の親があるかどうかを確認するドキュメント クラスに before_destroy コールバックを追加しますが、どのクラス (親) が破棄を呼び出しているかを知る必要があるため、どの外部キーを削除するかがわかります。どの親が破棄を呼び出しているかを知るにはどうすればよいですか?

ポリモーフィック アソシエーションを調査しましたが、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 コールバックとしてそれを行う方法はありますか? (私が好むのは、上記を参照)

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

2 つのクラスでコードを繰り返す必要がないように、おそらく何らかのヘルパーにメソッドを配置する必要があります。

于 2013-09-07T13:10:00.617 に答える