Rails:dependent =>:destroy VS:dependent =>:delete_all


192

レールガイドでは次のように説明されています:

オブジェクトは、に関連付けられている場合はさらに破棄:dependent => :destroyされ、に関連付けられている場合は削除されます:dependent => :delete_all

そうですね。しかし、破壊されることと削除されることの違いは何ですか?私は両方を試しました、そしてそれは同じことをするようです。

回答:


200

違いはコールバックです。

:delete_allアプリケーション内で直接行われ、SQLによって削除されます。

DELETE * FROM users where compagny_id = XXXX

を使用すると:destroy、すべての子供がインスタンス化されます。したがって、それを破棄できない場合、またはそれぞれに独自のがある場合:dependent、そのコールバックを呼び出すことができます。


83
多数の子がある場合(および孫がある場合はn ^ 2など)、子オブジェクトのそれぞれに対するインスタンス化とdestroyの呼び出しは遅くなります。delete_allは、モデルの破棄コールバックを気にする必要がない、または破棄コールバックの前後に何もない「軌道からの核攻撃」ソリューションの一種です。
ライアンビッグ

131

Railsのモデルの関連付けでは、:dependentオプションを指定できます。これは、次の3つの形式のいずれかになります。

  • :destroy/:destroy_all関連するオブジェクトは、そのdestroyメソッドを呼び出すことにより、このオブジェクトとともに破棄されます
  • :delete/:delete_all関連するすべてのオブジェクトは、:destroyメソッドを呼び出さずにすぐに破棄されます
  • :nullifyすべての関連オブジェクトの外部キーはNULLsaveコールバックを呼び出さずに設定されます

2
信頼できるrdocsについては、api.rubyonrails.org / classes / ActiveRecord / Associations /…(「nullify」を検索)を参照してください。
mrm

21
Rails 3.0以降では、を指定することもできます:restrict:restrictに設定すると、関連付けられたオブジェクトがある場合、このオブジェクトは削除できません。
RocketR 2011

17
それのルックスによってオプションがない:delete:destroy_all:dependentオプションは、:destroy、:delete_all、:nullifyまたは:restrict(:delete)のいずれかを想定しています
Mike Campbell

2
@MikeCampbell、:deleteおよび:destroy_allオプションは存在しません。しかし、と呼ばれているモデルのクラスメソッドが存在deleteし、destroy_allそれが混乱の原因かもしれません。
berezovskyi 14年

@MikeCampbellいくつかの追加オプションがありません。「:dependentオプションは[:destroy、:delete_all、:
nullify

30

参照してください。削除にその関連要素破壊DELETE_ALLが自己のテーブルから複数のデータを削除することができますようにDELETE * FROM table where field = 'xyz'

:依存可能なオプション:

所有者が破棄されたときに関連オブジェクトに何が起こるかを制御します。これらはコールバックとして実装され、Railsはコールバックを順番に実行することに注意してください。したがって、他の同様のコールバックが:dependent動作に影響する可能性があり、その:dependent動作は他のコールバックに影響する可能性があります。

:destroy 関連するすべてのオブジェクトも破棄されます。

:delete_all すべての関連オブジェクトがデータベースから直接削除されます(したがって、コールバックは実行されません)。

:nullify外部キーをNULLに設定します。コールバックは実行されません。

:restrict_with_exception 関連するレコードがある場合、例外が発生します。

:restrict_with_error 関連付けられたオブジェクトがある場合、所有者にエラーが追加されます。

:throughオプションとともに使用する場合、結合モデルの関連付けはbelongs_toである必要があり、削除されるレコードは、関連付けられたレコードではなく、結合レコードです。


3

実際の主な違いは、:delete_allが使用されたときにコールバックが呼び出されないことです。ただし、使用:destroyすると、コールバックスタック(:after_destroy:after_commit...)が発生します。

その結果、touch:削除されているモデルのing宣言がある場合dependent: :delete_allは、「dependent::destroy」を使用する方が適切です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.