39

私が2つのテーブルを持っていると仮定します:usersorders。ユーザーには多くの注文があるため、当然、注文テーブルには外部キーuser_idがあります。

ユーザーが削除された場合に、依存するすべての注文も削除されるようにするための、レールのベストプラクティス(速度、スタイル、および参照整合性の観点から)は何ですか?私は次のオプションを検討しています。

ケース1.:dependent => :destroyユーザーモデルでの使用

ケース2.postgresでのテーブルの順序の定義と書き込み

user_id integer REFERENCES users(id) ON DELETE CASCADE

ケース1を使用する理由はありますか?ケース2は私がやりたいことをすべてやっているようです。実行速度に違いはありますか?

4

3 に答える 3

37

それは本当にあなたが望む振る舞いに依存します。ケース1の場合、関連する各注文でdestroyが呼び出されるため、ActiveRecordコールバックも呼び出されます。ケース2の場合、これらのコールバックはトリガーされませんが、はるかに高速で、参照整合性が保証されます。

アプリケーションの初期段階で:dependent => :destroyは、データベースから独立した方法で開発できるため、一緒に使用することをお勧めします。スケーリングを開始したら、パフォーマンス/整合性の理由からデータベースでスケーリングを開始する必要があります。

于 2012-09-23T22:32:29.840 に答える
25

has_many :orders, dependent: :destroy

  • データの整合性を自動的に維持するための最も安全なオプション。
  • ポリモーフィックな関連付けがあり、トリガーを使用したくない場合。


add_foreign_key :orders, :users, on_delete: :cascade(データベース移行時)

  • ポリモーフィック アソシエーションを使用していないか、ポリモーフィック アソシエーションごとにトリガーを使用したい。


has_many :orders, dependent: :delete_all

  • has_many がアソシエーション ツリーのリーフ ノードである場合にのみ使用します (つまり、子は外部キー参照との別の has_many アソシエーションを持っていません)。
于 2015-06-28T20:11:15.563 に答える
8

オプション1を使用します。機能する可能性はありますが、オプション2にはいくつかの問題があります。

  1. ActiveRecordは、これらのレコードが削除されたことを認識しないため、動作が不安定になる可能性があります
  2. ユーザーを削除すると、すべての注文も削除されることをコードを読んでいる人にはわかりません。
  3. destroyOrderのハンドラーは起動しません

確かに、オプション2の方が速いと思いますが、トレードオフに値するかどうかはあなた次第です。ユーザーの削除は、アプリケーションで一般的な操作ですか?

別のオプションは、を使用すること:dependent => :delete_allです。これは、:dependent => :destroy上記の欠点1および2よりも高速であり、回避できます。詳細については、こちらをご覧ください。

于 2012-09-23T22:31:13.043 に答える