前人未踏の領域へ WEB・インフラ・プログラミング全般編

フロントエンド、バックエンド、インフラ、言語など、アプリ開発、IOT以外の記録

Rails destroyがdependent: :destroy から呼ばれたかどうかを知るには

課題

あるテーブルがすべて削除されたタイミングで親のテーブルを削除したい。 これを子テーブルのモデル側でやろうとすると、そのモデルの after_destroy で、belongs_to 関連を持つ親テーブルを 削除することになる。

これは普通に上手くいくが、楽観的排他を採用していた場合、親テーブルを直接 destory しようとした際にエラーとなる。 そこで親の dependent: :destroy によって destroy が呼ばれた場合には処理が実行されないようにしたい。どうすればよいか。

対応

destroyed_by_association を使うと削除されようとしている親のオブジェクトが返却されるので、それを利用する。

  after_destroy :destroy_parent

  private

  def destroy_parent
    # dependent: :destory 以外の場合のみ実行
    unless destroyed_by_association
       # 子が空になったら親を削除する
       self.hoge.destroy if self.hoge.children.empty?
    end
  end

参考

stackoverflow.com

apidock.com

/* Responsive: yes */