0

モデルに複雑なスコープがあり、パラメーターを満たすアクティブな取引をユーザーに提供します。

scope :deal_query, lambda { |m, p| where("meal = ? and active = ? and people LIKE '%?%' and inactive_days NOT LIKE '%?%'", m, true, p, Time.zone.now.wday)}

people 列はシリアル化され、数値の配列を格納します (LIKE sql ステートメントを使用してシリアル化された列を検索するためのハックです)。次に、このデータの配列をマップに渡します! ブロックは、ハッシュ内のすべてのデータをレンダリングします。

ブロックの縮小バージョンを次に示します。(補足、私はレールをAPIとして使用しており、これはjsonを返します)

Deal.deal_query(params[:meal].to_i, people).map! {|ld| {                                                                                            
:deal_id => ld.id, :title => ld.title, :description => ld.description}}

ブロックでは、人物列を 1 ずつ増やして、次に利用可能な取引の名前を送信しようとしています。次の利用可能な取引をチェックするブロックで別のクエリを実行したくありません。これは信じられないほど非効率的です。スケーリングされます。

次に利用可能な取引を積極的にロードする方法についての提案は役に立ちます。people 列を 1 インクリメントするだけで別のスコープを作成することを考えましたが、それを最初のスコープのデータとどのように一致させるかわかりません。

4

1 に答える 1

0

LIKE を次のように変更してみませんか。

where("... (people LIKE '%?%' OR people LIKE '%?%') ...", <etc>, p, p+1, <etc>)

つまり、両方を一度に取得してから、結果に対して必要なことを行います。通話の目的と、「次に利用可能な取引の名前」の意味についてはよくわかりませんがmap!、その時点でオブジェクトから必要なデータを引き出すことができるはずです。完全な AR モデルで遊べます。

スケーラビリティについてさらにヘルプが必要な場合は、DB スキーマを確認する必要があります。これは、あなたが示したものからかなりハックタスティックに感じます-人の列を処理するためのよりエレガントでパフォーマンスの高い方法がある可能性があります...

于 2013-03-02T01:23:15.807 に答える