先に結論:
restrict_with_exception
オプションとは:
- 親レコードを削除するとき、子レコードがある場合は
ActiveRecord::DeleteRestrictionError
が発生して削除できない - 子レコードを先に削除しないと、親レコードを削除できないオプションのこと
詳細
Rails のdependent
オプションとは、親のレコードを削除したとき、子レコードの扱いをどうするか決める機能。
よく見るのはおそらくdependent: :destroy
で、親レコードを削除したときには子レコードも一緒に削除するといったもの。
今回はdependent
オプションのひとつ、dependent: :restrict_with_exception
について学んだ。
参考記事:dependent: :restrict_with_error と :restrict_with_exception の違い - Qiita
:restrict_with_exception
オプションをつけると、親レコードを削除するとき、子レコードがある場合はActiveRecord::DeleteRestrictionError
が発生する。つまり削除できない。そのため、子レコードを先に削除しておく実装が必要になる。
たとえば、下記のようなモデル構成の場合。
class Category < ApplicationRecord has_many :items, dependent: :restrict_with_exception end
この場合、item を削除してからじゃないと、category を削除できない。category を先に削除しようとすると、ActiveRecord::DeleteRestrictionError が発生する。
deleteメソッド
ちなみに、destroyメソッドに似たものとして、deleteメソッドがある。destroyはActiveRecordを介するため、関連付けの設定を呼ぶ。
deleteメソッドは、ActiveRecordを介さずに直接SQLを発行する。つまりバリデーションを無視する。また、関連付けされているレコードがあったとしても、そちらは削除されない。
https://api.rubyonrails.org/classes/ActiveRecord/Associations/CollectionProxy.html#method-i-delete