LoginSignup
2
2

More than 1 year has passed since last update.

[ActiveRecord]dependentオプションの使い分け方

Last updated at Posted at 2021-06-18

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】

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2