0

ビューにアイテムのリストを表示しています。私のコントローラ クラスは、リストを取得するために sql を実行します。また、リストがフェッチされたら、テーブル内のいくつかの値を更新しています。問題は、選択ステートメントの前に値が設定されていることです。以下はコントローラーのコードです。

@orders = List.select("itemname,tableno,quantity,itmstatus").where(:tableno => "01")
List.where(:tableno => "01").update_all(:ordstatus => 'displayed',:itmstatus => 'displayed')

私のビューには、 で取得されたさまざまなフィールドが表示されます@orders。itemstatus 値に基づいて、ビューにテキストの色コードを設定する必要があります。そのため、select ステートメントが実行されたら、itmstatus 値を別の値に設定します。しかし、私の見解では、@orders には更新された値があります (選択後に実行しています)。サーバー側でチェックしたところ、select ステートメントは update ステートメントの後に実行されます。これは、@orders の値を更新した場合に当てはまると思われます。選択後に更新ステートメントを実行する方法はありますか。以下と他のいくつかのオプションを試しましたが、うまくいきませんでした。

if @orders
 @orders = List.select("itemname,tableno,quantity,itmstatus").where(:tableno => "01")
 List.where(:tableno => "01").update_all(:ordstatus => 'displayed',:itmstatus => 'displayed')
end

お知らせ下さい。ありがとう。

4

1 に答える 1

2

問題は、ビューがインスタンス変数を列挙するときにコード@orders = List.select("itemname,tableno,quantity,itmstatus").where(:tableno => "01")遅延評価されることです。@ordersつまりActiveRecord::Relation、ビューがレンダリングされるときにのみ実際に評価される (SQL が実行される) だけです。

これを防ぐ 1 つの方法は、クエリを完全に実行し、後で更新ステートメントの前にすべての行を取得するto_aことActiveRecord::Relationです。

@orders = List.select(...).where(...).to_a

注意すべきことの 1 つは、Kaminari をページネーションに使用している場合、通常の Kaminari ページネーション拡張機能が機能しないことです。使用する必要がありますKaminari::paginate_array

考慮すべきもう 1 つの点は、クエリが大量のレコードを返す可能性があるかどうかです。呼び出すto_aことで、ActiveRecord にすべてのレコードを一度にメモリに取得するように指示することになり、パフォーマンスが低下する可能性があります。

Rails 3 では、.allメソッド (のようにList.select().where().all) を使用してクエリを実行および評価することも可能です。ただし、Rails 4 では、Model.allと同等にModel.scopedなり、遅延評価されるようになったため、.to_a


ActiveRecord::Relation#loadまたは、次のメソッドを確認することもできます。

まだロードされていない場合、データベースからレコードがロードされます。何らかの理由で、実際に使用する前にいくつかのレコードを明示的にロードする必要がある場合に、これを使用できます。戻り値は、レコードではなくリレーションそのものです。

確かに、私は実際にそれを使用したことはありませんが、この場合はより適切かもしれません.

于 2013-08-29T10:07:03.260 に答える