動かざることバグの如し

近づきたいよ 君の理想に

Railsで削除時にネストしたモデルも削除する

環境

やりたいこと

Railsでは 1対多 とか 多対多 の関係のときに親レコードを削除したときにそれに紐づく子レコードも一緒に削除することができる。方法は簡単で has_many(has_one)にdependent: :destroyを追加するだけ

ここで以下のようなparent>child>grandchildのモデルが合ったとする。これでparentレコードを削除したときにchildもgrandchildも自動で削除できるようにしたい。

parent.rb

class Parent < ApplicationRecord
  has_many :childs
end

child.rb

class Child < ApplicationRecord
  belongs_to :parent
  has_many :grandchilds
end

grandchild.rb

class Grandchild < ApplicationRecord
  belongs_to :child
end

やり方

parent.rbdependent: :destroy を追加し、child.rbdependent: :delete_all を追加する。

parent.rb

class Parent < ApplicationRecord
  has_many :childs, dependent: :destroy
end

child.rb

class Child < ApplicationRecord
  belongs_to :parent
  has_many :grandchilds, dependent: :delete_all
end

なんでchild.rbはdelete_allなの

dependent: :destroy だと削除するときActiveRecord経由で削除するのでコールバックも発生するし1レコードずつ削除するので、 モデルchildとgrandchildのレコード数が多いとめっちゃ遅くなる。

dependent: :delete_allにすると直接SQLで削除されるので1SQLで一発で削除される。

参考リンク