dependentオプションとは?
モデルのレコードがdestroyされたときの、関係付けされたモデルに対する挙動を定義するものです。
:destroy
関連付けられたモデルに対してもdestroyを実行することが出来る。
class User < ApplicationRecord
# Userが削除された際に、それに関連付いているarticlesも削除される
has_many :articles, dependent: :destroy
end
使い分け
- 削除時に、指定したモデルのレコードも同時に削除したい場合。
-
ActiveRecoreを介して
destroyに関連した処理も実行したい場合。 - 速度・サーバ負荷を気にする必要がない場合。
:delete/:delete_all
destroy時に指定したモデルに対して、ActiveRecordを介せずに直接SQLクエリ(DELETE)が実行
されます。
class User < ApplicationRecord
# has_manyの場合は:delete_allと記述
has_many :articles, dependent: :delete_all
# belobgs_to, has_oneの場合は:deleteと記述
belongs_to :group, dependent: :delete
end
使い分け
- 削除時に、指定したモデルのレコードも削除したい。
-
ActiveRecordを介さず
、destroyに関連したフックを実行したくない。 - 速度・サーバ負荷が気になる場合(高速処理が可能なため)。
:nullify
destroy時に指定したモデルの外部キーにnullが入れる。
※UPDATEのみなのでDELETEより負荷は軽いです。
class User < ApplicationRecord
# Userが削除された際に、それに関連付いているarticlesのuser_idがnilに更新される
has_many :articles, dependent: :nullify
end
使い分け
- 削除されたレコードは残しておきたいが、参照先のない外部キーは防ぎたい場合。
- レコードが増え続けても問題がない場合。
- 自分のタイミングで削除を行いたい場合。
- DELETEする負荷に耐えられない場合。
:restrict_with_exception
親レコードを削除するとき、子レコードがある場合はActiveRecord::DeleteRestrictionErrorを発生させる。
そのため、子レコードを先に削除しておく実装が必要になる。
class Category < ApplicationRecord
# itemを削除してからでないと、categoryを削除できない
has_many :items, dependent: :restrict_with_exception
end
使い分け
- 子要素があるときに削除されては困る場合。
:restrict_with_error
親レコードを削除するとき、子レコードがある場合は削除できず、親レコードにエラー情報が付加される。
class Category < ApplicationRecord
# itemが関連付いている場合は、categoryを削除できずにエラー情報が付加される
has_many :items, dependent: :restrict_with_exception
end
使い分け
- 子要素があるときに削除されては困る場合。
参考
[【Rails】ActiveRecordの:dependent使い分けまとめ【:destroy, :delete, :nullify】]
(https://dorarep.page/articles/rails-dependent)