0

現在、予測されたスコアによってユーザーのグループを一覧表示する非常に非効率的なビューパーシャルがあります。

グループコントローラー

def show

  @sfs_ordered = ScoreFootballSimple.order("home_score DESC, away_score ASC")
  @live_games = Game.find(:all, :conditions => ['kickoff <  ?  AND completed != true AND game_state is NOT NULL', Time.now])

group#show(関連セクション)

<% @live_games.each do |game| %>
  <% @sfs_ordered.each do |sfs| %>
    <% got_this_score = Array.new %>
    <% game_points = nil %>
    <% @group.members.each do |member| %>
      <% if pred = member.prediction_set.predictions.where('game_id = ?',game.id).first %>
        <% game_points = pred.points if !pred.points.nil? && pred.score_type == sfs.score_type %>
        <% got_this_score << member.user.user_detail.display_name if pred.score_type == sfs.score_type %>
      <% end %>
    <% end %>
    <% if got_this_score.count > 0 %>
      <tr><td><%= sfs.home_score %>-<%=sfs.away_score%></td>
      <td><% if !game_points.nil? %>
            <div class="preds-show-points-div"><%= game_points %>pts</div>
          <% else %>
             -
          <% end%></td>
       <td><%= got_this_score.to_sentence %></td></tr>
     <% end%>
  <% end %>
<% end %>

明らかに、これはループ内のループです。つまり、すべての@sfs_ordered(約50レコード)に対して、すべてのグループメンバー(最大のグループの場合は約5000)に対して反復処理され、ページの読み込みに数秒かかることを意味します。

私を怒らせないでください、これはそれがどのように見えるかを示すためのPOCでしたが、ActiveRecordの能力の欠如を明らかにしました。これで、ユーザーのハッシュや予測セットなどを作成することができましたが、Railsクエリを使用してより正確に情報を選択するためのより良い方法を誰かに教えてもらえないかと思いました。

実体関連は次のようなものです

  • グループには多くのメンバーがいます
  • メンバーはUserPredictionSetに属しています
  • PredictionSetには多くのPredictionがあります
  • 予測はGameScoreTypeに属します
  • ScoreTypeSimpleには1つのScoreTypeがあります

予測されるスコアはScoreTypeSimpleにあります-これがリストを整理する方法です

例:1:1-ジョー、フレッド、ジェーン1:0-スー、デイブ、ヘレン

次に、グループ.member.prediction_set.predictionのグループ.member.user.nameを取得します。ここで、prediction.game.id == game.id AND score_type == sfs.score_type

純粋なSQL結合とINおよびビルドハッシュによってこれを改善できることは知っていますが、Rails / Rubyでこれを効率的に行う方法があれば、誰かが私にポインターを与えることができるかどうか疑問に思いました。私は答えがおそらくラムダにあることを知っていますが、私のActiveRecordの知識はここで限界まで伸びています!

ありがたいことにどんな助けも受けました。

ピーター

4

1 に答える 1

0

いくつかの関連オブジェクトをすべて表示しているので、積極的な読み込みの恩恵を受けることができるかもしれません。これは.includes、リレーションのメソッドを使用して行われます。たとえば、ビューはグループのすべてのメンバーで機能するため、データベースからグループをフェッチすると(コードにこれを行う行は表示されませんが、おそらく次のようになります)

@group = Group.where('some condition').first

代わりにこれを使用する場合:

@group = Group.includes(:members => [:user]).where('some condition').first

次に、グループ、そのすべてのメンバー、およびすべてのユーザーオブジェクトをロードするのは、(極端な場合は5000メンバーの場合)10,001ではなく、3つのデータベースクエリです。

これはせいぜいあなたの解決策のごく一部だと思いますが、それは役立つかもしれません。

編集:これが積極的な読み込みに関するRailsCastであり、このページの半分ほど下にいくつかのドキュメントがあります。

于 2012-06-11T14:30:48.007 に答える