dependent 関連元が削除された時の関連先に対する操作を指定する
使用可能な関連付け
belongs_tohas_manyhas_one
対となる関連に指定するオプション
なし
概要
関連元が削除された時の関連先に対する操作を指定する。
関連ごとに指定できるオプションが異なる。
未指定またはdependent: nil
belongs_tohas_manyhas_one
で利用可能。
何もしない。
dependent: :destroy
belongs_tohas_manyhas_one
で利用可能。
指定した関連先に対してdestroyを実行する。destroyなのでコールバックなども実行される。
dependent: :delete
belongs_tohas_one
で利用可能。
指定した関連先に対してdeleteを実行する。deleteなのでコールバックなどは実行されずにDELETE文が実行される。
dependent: :delete_all
has_many
で利用可能。
指定した関連先に対してdeleteを実行する。deleteなのでコールバックなどは実行されずにDELETE文が実行される。
dependent: :destroy_async
belongs_tohas_manyhas_one
で利用可能。
関連先に対してdestroyを実行するJobを登録する。Active Jobが必要。同一トランザクションで削除する必要がなく、パフォーマンスなどの理由で非同期に削除したい場合に使う。外部キー制約が指定されている場合は同一トランザクションで削除しないといけないため、このオプションは利用できない。
dependent: :nullify
has_manyhas_one
で利用可能。
関連先の外部キーにNULLを設定する。ポリモーフィック関連の場合はtypeカラムもNULLにする。コールバックは実行されない。
dependent: :restrict_with_exception
has_manyhas_one
で利用可能。
関連先が存在している場合はActiveRecord::DeleteRestrictionError例外を投げる。
dependent: :restrict_with_error
has_manyhas_one
で利用可能。
関連先が存在している場合はerrorsにエラーが追加される。
スコープとの組み合わせ
class Blog < ApplicationRecord
has_many :entries, -> { where(published: true) }, dependent: :destroy
end
上記のようにスコープと組み合わせている場合、スコープで絞り込まれた対象だけがdependentオプションの対象となる。なので、上記の例ならpublished: falseなEntryがあれば外部キーもそのままの状態で残り続けてしまう。
双方向関連における belongs_to :..., dependent: ...
class Blog < ApplicationRecord
has_many :entries
end
class Entry < ApplicationRecord
belongs_to :blog, dependent: :destroy
end
上記のような実装をした状態で、Entry.last.destroyを実行した場合、Entry.lastとEntry.last.blogの2レコードは消えるが、Entry.last以外のEntry.last.blog.entriesのレコードは残り続けてしまう。
このような結果を避けたい場合は、has_manyの方にもdependentオプションを指定する。
class Blog < ApplicationRecord
has_many :entries, dependent: :destroy
end
class Entry < ApplicationRecord
belongs_to :blog, dependent: :destroy
end
throughオプションとの組み合わせ
検証してみたが挙動がよくわからない。