テーブルからレコードを削除する最良の方法を探しています。たとえば、ユーザーIDが多くのテーブルにまたがっているユーザーがいます。このユーザーと、すべてのテーブルで彼のIDを持つすべてのレコードを削除します。
u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
u.sources.destroy_all
u.user_stats.destroy_all
u.delete
これは機能し、すべてのテーブルからユーザーのすべての参照を削除しますが、destroy_all
は非常に処理が重いと聞いたので、delete_all
を試しました。自分のユーザーテーブルからユーザーを削除するだけで、他のすべてのテーブルのid
はnullになりますが、レコードはそのまま残ります。誰かがこのようなタスクを実行するための正しいプロセスを共有できますか?
destroy_all
が関連するすべてのオブジェクトでdestroy
関数を呼び出すことがわかりましたが、正しいアプローチを確認したいだけです。
あなたが正しいです。ユーザーとすべての関連オブジェクトを削除する場合-> destroy_all
ただし、すべての関連オブジェクトを抑制せずにユーザーを削除する場合-> delete_all
この投稿によると: Rails:dependent =>:destroy VS:dependent =>:delete_all
destroy
/destroy_all
:関連するオブジェクトは、destroyメソッドを呼び出すことにより、このオブジェクトとともに破棄されますdelete
/delete_all
:すべての関連オブジェクトは、:destroyメソッドを呼び出さずにすぐに破棄されますdelete_allは単一のSQL DELETEステートメントであり、それ以上のものはありません。 destroy_allは、少なくともNUM_OF_RESULTS個のSQLステートメントである可能性のある:conditions(ある場合)の一致するすべての結果に対してdestroy()を呼び出します。
大規模なデータセットでdestroy_all()などの抜本的な操作を行う必要がある場合は、おそらくアプリから実行せず、注意して手動で処理します。データセットが十分に小さければ、それほど害はありません。
destroy_all
がすべてのレコードをインスタンス化し、一度に1つずつ破棄するという事実を回避するために、モデルクラスから直接使用できます。
代わりに:
u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
できるよ :
u = User.find_by_name('JohnBoy')
UsageIndex.destroy_all "user_id = #{u.id}"
結果は、関連するすべてのレコードを破棄する1つのクエリです
small gem を作成しました。これにより、状況によっては関連するレコードを手動で削除する必要性を軽減できます。
このgemは、ActiveRecord関連付けの新しいオプションを追加します。
依存::delete_recursively
レコードを破棄すると、このオプションを使用して関連付けられているすべてのレコードは、それらをインスタンス化せずに再帰的に(つまり、モデル間で)削除されます。
Dependent::deleteまたはdependent::delete_allと同様に、この新しいオプションは依存レコードのaround/before/after_destroyコールバックをトリガーしないことに注意してください。
ただし、dependent::delete_recursivelyに関連付けられているモデルのチェーン内の任意の場所にdependent::destroy関連付けを設定することは可能です。 :destroyオプションは、行の上下のどこでも正常に機能し、関連するすべてのレコードをインスタンス化して破棄し、コールバックもトリガーします。