dependent 関連元が削除された時の関連先に対する操作を指定する
使用可能な関連付け
belongs_to
has_many
has_one
対となる関連に指定するオプション
なし
概要
関連元が削除された時の関連先に対する操作を指定する。
関連ごとに指定できるオプションが異なる。
未指定またはdependent: nil
belongs_to
has_many
has_one
で利用可能。
何もしない。
dependent: :destroy
belongs_to
has_many
has_one
で利用可能。
指定した関連先に対してdestroy
を実行する。destroy
なのでコールバックなども実行される。
dependent: :delete
belongs_to
has_one
で利用可能。
指定した関連先に対してdelete
を実行する。delete
なのでコールバックなどは実行されずにDELETE文が実行される。
dependent: :delete_all
has_many
で利用可能。
指定した関連先に対してdelete
を実行する。delete
なのでコールバックなどは実行されずにDELETE文が実行される。
dependent: :destroy_async
belongs_to
has_many
has_one
で利用可能。
関連先に対してdestroy
を実行するJobを登録する。Active Jobが必要。同一トランザクションで削除する必要がなく、パフォーマンスなどの理由で非同期に削除したい場合に使う。外部キー制約が指定されている場合は同一トランザクションで削除しないといけないため、このオプションは利用できない。
dependent: :nullify
has_many
has_one
で利用可能。
関連先の外部キーにNULLを設定する。ポリモーフィック関連の場合はtypeカラムもNULLにする。コールバックは実行されない。
dependent: :restrict_with_exception
has_many
has_one
で利用可能。
関連先が存在している場合はActiveRecord::DeleteRestrictionError
例外を投げる。
dependent: :restrict_with_error
has_many
has_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
オプションとの組み合わせ
検証してみたが挙動がよくわからない。