2012-06-07 8 views
7

ドリルを知っています:いくつかの無効なデータが本番データベースにポップアップしてしまいます。あなたは、クエリ内で運用サーバーおよびタイプにあなたのRailsコンソールを起動:Railsでdelete_allまたはdestroy_allクエリをプレビューする方法

Foo.where(bar: 'baz').all 

あなたが返されたデータを検討し、それはあなたが削除する必要があるものです。次に入力します。

Foo.where(bar: 'baz').destroy_all 

あなたの心は1秒間停止します。クエリが実行される前にそれを見たいだけです。

これをRailsで実行する方法はありますか?私は

Foo.where(bar: 'baz').to_sql 

しかし DELETEクエリ返しますのと同様の方法を探しています。

答えて

1

サンドボックスモードでコンソールを実行し、削除クエリを実行してsqlを表示することができます。変更は単に終了時にロールバックされます。

+0

私はこれは本当にないと仮定あなたが本当に "to_sql"のような通信を探しているなら、あなたの質問に答えてくださいそして。 – cdesrosiers

+0

私はサンドボックスモードを完全に忘れてしまった!それはまさに私が探していたものではありませんが、私はそれが必要なことを正確に行います。 D –

2

問題は、destroy_allは単一のSQLクエリを実行しないということです。オブジェクトのハッシュを反復してインスタンス化し、コールバックを実行した後、そのオブジェクトのdestroyメソッドを呼び出します。 Railsには、これらのクエリの配列を生成する方法が組み込まれていません。

サンドボックスモードでクエリをテストできるのは正しいですが、実際の問題は、ターゲットとなるデータを確認したにもかかわらず、あなたがdelete_allを実行するという決定を二度と推測しているということです。

オブジェクトを適切に削除するためにActiveRecordを信頼したくない場合は、PaperTrailのようなActiveRecordのバージョンング・ギフトを使用することを検討してください。

+0

バッチ処理として 'delete_all'を実装していない理由は何ですか?データベースへの往復を深刻にするのではなく、バッチ処理で行うほうがはるかに安いと思いました。 – Bedasso

+2

delete_allはバッチ処理です。 destroy_allはそれらを1つずつ実行します。 delete_allは速いのでdestroy_allは破棄コールバックの前後に起動するので便利です。 –

+0

PaperTrailはアプリでの使用には最適ですが、冗長なデータを取り除くだけで済みました。とにかくありがとう! –

1

destroy_all方法がやってと同じです:

Foo.where(bar: 'baz').each { |object| object.destroy } 

ように、SQLは、ドキュメントから

DELETE FROM foo WHERE foo.id = your_objects_id_attribute 



次のようになります。

def destroy_all(conditions = nil) 
    find(:all, :conditions => conditions).each { |object| object.destroy } 
    end 
+1

私は、生成されたSQLは、複数のDELETEクエリで構成されると考えています。 – mrt

関連する問題