2009-07-27 8 views
2

Railsアプリケーションでは、私はマイグレーションとは別に、それらをすべて手動で設定したMySQLで外部キー制約を持っています。ON DELETE CASCADE、:dependent =>:destroy、またはその両方を使用する必要がありますか?

ActiveRecordの:dependent => :destroyオプションを使用するかどうかを判断しようとしています。例えば、私のスキーマに、私はテーブルを持っている...

users 
----- 

log_entries 
----------- 
user_id # Has FK constraint to users.id with ON DELETE CASCADE 

そして、私のモデルに私が...

class User < ActiveRecord::Base 
    has_many :log_entries, :dependent => :destroy 
end 

は、私がモデルに依存してオプションを省略すると、ちょうどそれを残すべきかもしれませんDBまで?それともそれを持っているのがいいですか?このアプリケーションでは、削除するときにコールバックを実行する必要はありません。すべての場合、単に削除するだけで問題ありません。

考慮すべきもう1つの要因は、おそらくrake db:test:prepareがそれらを設定していないため、FK制約がテスト環境に存在しないということです。だから、MySQLに完全に依存して削除をカスケードするのであれば、何が起こるかをテストするのは難しいです。

答えて

6

ON DELETE CASCADEでFKを使用している場合は、モデルでdependent =>:destroyを使用しないでください。それは不要なクエリを実行する可能性があり、将来的に何かを壊さないようにすることはできません。起こっていることを記録するために、モデルファイルにコメントを書き込む必要があります。しかし、。

移行でもFKを実行することをおすすめします。テストデータベースが本番データベースと同じ制約を受けていると、非常に不正なバグが発生する可能性があります。移行時に外部キーを簡単にするRedHillプラグイン(redhillonrails_core)があり、FK制約付きのスキーマダンプが可能になるので、テストははるかに簡単です。

+0

なぜあなたはそれを信じられませんか? Model.to_jsonを使用するべきだと言っているように、それは将来破らないことを保証しないからです。 –

+0

依存関係の別の層があり、フックがトップダウンを削除することを決定した場合、レコードが期待できないときにレコードが消えるとnilの呼び出しメソッドが呼び出される可能性があります。 –

+0

あなたのデータベースには、レールアプリではなくデータを管理させるのが理にかなっています。削除カスケード時の使用法の保護。 schema_formatを次のように設定するべきではありません:sqlは、テストデータベースの問題でカスケードが存在しないことを修正しますか? –

3

私は以下のように追加します:dependent =>:意図を伝えるだけで、それを破壊します。さらに重要なのは、すべてのデータベースがDELETE CASCADEをサポートするとは限らないため、関連するレコードを最適に削除する方法を決定する責任がデータベースアダプタにあります。私の意見では、少なくともそれをモデルに入れることがより重要です。しかし、それを両方に入れることは正解です。

+0

完全にあなたに同意します。私はAPPLICATION側のモデルの依存関係は、データベースとアプリケーションをバインドしないため、必要な部分であると考えています。また、データベース側のカスケード削除は、データベースを直接操作する際に問題が発生しないことを保証します。 –

3

に依存します。 :dependent =>:destroyは各子モデルをロードし、はコールバックを実行します。 ON DELETE CASCADEはコールバックを実行しませんが、雷が激しくなります。

モデルを削除したい場合は、ON DELETE CASCADEを使用するか、またはN + 1の代わりに1つのクエリのみを実行するdependent =>:delete_allを使用します。

+1

私の意見では、これはトレードオフです。一方では、すべてのビジネスルールを無視して、データを破壊する稲妻の速い方法があります。もう1つは遅いですが(実際には遅いかもしれませんが)ビジネスロジックを尊重します。どちらの方法も私には有効です。 – lsdr

関連する問題