不要なクエリをトリガーすることなく、Railsのhas_many関連付けからレコードを削除するのに問題があります。基本的には、has_manyリレーションを持つモデルがあり、いくつかの基準に基づいて複数のレコードを削除したいと考えています。私はアソシエーションを最新の状態に保ちたいだけでなく、データベースからレコードを削除し、これを行うために1つのDELETEクエリを必要とします。私は新しいオブジェクト(不要なUPDATEクエリを生成する)とdelete_all(1つのクエリを作成するが、関連付けを更新しない)を呼び出すという関係に割り当てようとしました。has_manyからレコードを削除する単一のクエリとのRails関連付け
1
A
答えて
0
リレーションからレコードを削除するには、2つの方法があります。 destroy
は、すべての関連レコードを1つずつ削除し、削除されたレコードごとにコールバックを実行します。 delete_all
は、1つのクエリ内のすべてのレコードを削除し、コールバックを実行しません。
ので、モデルにあなたが持っている可能性があり:あなたは顧客に
pry(main) foo = Customer.first
pry(main)> foo.destroy
(0.3ms) BEGIN
SQL (290.4ms) DELETE FROM `statements` WHERE `statements`.`customer_id` = 3
SQL (2.6ms) DELETE FROM `customers` WHERE `customers`.`id` = 3
すべてが1うねりfoopで行わを削除すると
class Customer < ApplicationRecord
has_many :statements, dependent: :delete_all
をして、にはコールバックは削除されません。
か -
class Customer < ApplicationRecord
has_many :statements, dependent: :destroy
、あなたが顧客に
pry(main) foo = Customer.first
pry(main)> foo.destroy
(0.4ms) BEGIN
Statement Load (25.0ms) SELECT `statements`.* FROM `statements` WHERE `statements`.`customer_id` = 4
SQL (0.5ms) DELETE FROM `statements` WHERE `statements`.`id` = 9023
SQL (0.3ms) DELETE FROM `statements` WHERE `statements`.`id` = 9024
SQL (0.3ms) DELETE FROM `statements` WHERE `statements`.`id` = 9025
. . . etc etc etc . . .
を削除すると、各従属レコードは一度に一つ、各削除で実行するコールバックを削除しました。
delete_all
およびdestroy
は、同様の効果を持つ結果セットで実行できます。あなたは関連レコードにいくつかのフィルタを持っていると思ったのであれば:
pry(main) foo = Customer.first
pry(main)> bar = foo.statements.where(some_param: 42)
pry(main)> bar.delete_all
SQL (4.2ms) DELETE FROM `statements` WHERE `statements`.`customer_id` = 7 AND `notices`.`some_param` = 42
=> 2
か -
pry(main) foo = Customer.first
pry(main)> bar = foo.statements.where(some_param: 42)
pry(main)> bar.destroy_all
(0.2ms) BEGIN
SQL (0.6ms) DELETE FROM `notices` WHERE `notices`.`id` = 4639
(0.5ms) COMMIT
(0.2ms) BEGIN
SQL (0.5ms) DELETE FROM `notices` WHERE `notices`.`id` = 4640
(0.4ms) COMMIT
(0.1ms) BEGIN
SQL (0.5ms) DELETE FROM `notices` WHERE `notices`.`id` = 4641
(0.5ms) COMMIT
. . . etc etc etc . . .
関連する問題
- 1. belongs_toとhas_manyの関連付けのコメントを削除する
- 2. has_manyとbelongs_toのRailsモデルの関連付けを作成する
- 3. Rails 4、has_many関連 - 関連付けられたオブジェクトを見つける
- 4. Railsのhas_manyの関連付け:私は、次の2つの関連付けを持って、関連するオブジェクト
- 5. 関連するレコードを削除すると、元のファイルが削除されます.Railsでhas_many関連ゲッターを削除します。
- 6. Railsにhas_oneとhas_manyの関連付けをしました
- 7. 関連付けられたテーブルからレコードを削除するPHP
- 8. has_manyとbelongs_toの関連付けのラジオボタン
- 9. RSpecとのhas_manyの関連付け
- 10. Rails has_many:親の "show"ビューでの関連付けと関連モデルの作成
- 11. レコードに関連付けられているレコードからレコードを除外する
- 12. Railsアクティブなレコード数の関連付け
- 13. Railsクエリ:associationは親の最初に関連付けられたレコードですか?
- 14. Rails3スコープとhas_manyの関連付け
- 15. Rails:フォーラムhas_manyトピック、関連付けを保存しますか?
- 16. Rails "foreign_key"との "has_many"関連
- 17. フォルダからレコードに関連付けられたイメージを削除します。
- 18. レール関連、単一のレコードだけ
- 19. Railsのhas_manyと外部キーとの関連付けを拡張する
- 20. Ruby has_many関連するモデルとPostgresデータベース(Rails 5)とのクエリ
- 21. アクティブレコードとの関連付けによって、has_manyの関連するレコードが見つからないレコードを見つける方法はありますか?
- 22. Rails 5 - Activerecordの関連付けクエリ
- 23. Rails - 関連付けられたレコードのデータを取得
- 24. Rails 4 - 1対1の関連付けで保存/削除
- 25. Railsは個別の参照とhas_manyの関連付けを行います
- 26. の追加とhas_manyのから削除:Railsの団体ガイドから関係
- 27. has_many、Ectoでの関連付け
- 28. Railsのhas_manyの関連
- 29. Railsは4にhas_many経由:フィルタリング関連するモデルの両方からレコード
- 30. 単一テーブル継承に関連付けられたHABTM関連
Railsは 'それぞれが'(before_'をコールバックを実行するために、削除したいオブジェクトを見つける必要があるとafter_' destroy)を実行します。滑らかな斜面であるそのプロセスをスキップしたい場合は、この「すべての関連オブジェクトを削除する」に関するすべてのロジックを保持し、アソシエーションをリセットするサービスオブジェクトを作成したい場合があります。 – MrYoshiji
アソシエーションをリセットすることも最適ではないと思います。後でアソシエーションがアクセスされると、リレーション内に何が含まれるべきかを知っていても、オブジェクトを再取得する必要があるからです。 – mp94
IMOでは、SQLクエリを減らしたり、Railsの動作を再定義したりしないでください。最初の視界では見えませんが、アプリ全体が何ヶ月間もそれを使用していたときに、多くの問題が発生する可能性があります。 – MrYoshiji