2016-05-16 9 views
0

私は、JSONフィールドを持つ製品テーブルを持っているので、そのメソッドを更新する必要があります。だから、二つのアプローチレール内でupdate_all内の自己オブジェクトを呼び出す

Product.all.each do |pr| 
    pr.update_column(:boolean_tree, pr.change_boolean_tree) 
end 

がある離れパフォーマンスからこのは何も問題はありません。パフォーマンスを向上させるために、raw SQLを実行できます。それは間違いなくうまくいくが、レールの方法ではない。

このような状況では、update_allを使用することが考えられました。何か案が ?

+0

SQLからルビメソッド( 'change_boolean_tree')を呼び出す方法はありません。大規模なSQLクエリの値を事前計算することはできますが、これは大量の 'INSERT INTO'に対しては簡単ですが、' UPDATE'には巨大な 'CASE'文が必要です。私は1回限りのスクリプトでない限り、後者に対して助言したいと思います。これをさらに複雑にするのは、列がJSONデータであるという事実です。 JSONデータの生のSQLに相当する 'change_boolean_tree'を書くことができるなら、それは実行可能です。私が見ているように、それらはあなたのデータ構築に与えられた2つのオプションです。 –

+0

@AndrewSchwartzはい私はこのアプローチを知っています。それをする方法があれば考えていた。 –

+0

あなたのご意見が分かりません。あなたはこれらの2つのアプローチのうちの1つを試しましたか?結果は何でしたか?ステートメント自身は概念的に構築するのが非常に簡単で、標準的なRailsの保護や利便性を提供していないので、何かを壊すのは簡単になります。 –

答えて

2

私が知る限り、同じ内容のすべてのレコードを更新しようとしない限り、update_allを使用することはできません。データベースに多くの製品がある場合、命令は、更新を開始する前にすべてのレコードをメモリにロードします。

アクティブレコード(see doc)のfind_in_batchesメソッドを使用して、バッチで商品を読み込むことをおすすめします。

+1

'update_all'は、SQLの断片を書く場合、異なる内容で使うことができます。 'model_update_all(" field1 = some_sql_function_on(field2) ")' –

+0

この場合、 'change_boolean_tree'はSQL関数ではなくルビ関数であるようです。あなたの褒め言葉はルビー関数で動作しますか? – Bustikiller

+0

いいえ、このフォームを使用するには、SQL関数としてrubyメソッドを記述する必要があります。 'boolean_tree'がJSONデータであるため、かなり難しいです。もう1つのオプションは、提案したようなバッチでロードし、ルビで更新された値を事前計算し、SQLフラグメントの事前計算値を使用して 'products.id'に' CASE'ステートメントを作成することです。本当に、本当にかさばる、それは動作します。 –

関連する問題