Rails 3.2.2查询子子属性建议

时间:2012-06-11 10:46:55

标签: ruby-on-rails-3 activerecord

目前,视频部分效率非常低,可根据预测得分列出用户组。

组控制器

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])

组#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查询更精确地选择信息的更好方法。

实体关系是这样的

  • 群组有很多会员
  • 会员属于用户 PredictionSet
  • PredictionSet 有许多预测
  • 预测属于游戏 ScoreType
  • ScoreTypeSimple 有一个 ScoreType

预测得分为 ScoreTypeSimple - 这就是我希望列表组织的方式

例如1:1 - Joe,Fred和Jane     1:0 - 苏,戴夫和海伦

然后我想获取群组 .member.prediction_set.prediction的群组 .member.user.name - 其中prediction.game.id ==游戏.id AND score_type == sfs.score_type

我知道我可以通过纯SQL连接和INs以及构建哈希来改进这一点,但我想知道是否有任何人可以给我任何指针,如果有一个Rails / Ruby有效的方法这样做。我知道答案可能在lambda中,但我的ActiveRecord知识在这里已达到极限!

感激不尽的任何帮助。

彼得

1 个答案:

答案 0 :(得分:0)

您可能可以从急切加载中受益,因为您正在显示所有相关对象。这是在关系上使用.includes方法完成的。例如,您的视图适用于组的所有成员,因此当您从数据库中获取组时(我没有看到在您的代码中执行此操作的行,但它可能看起来像

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

如果你改为使用它:

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

然后加载组,其所有成员以及所有用户对象是3个数据库查询,而不是(在极端情况下为5000个成员)10,001。

我认为这至多只是解决方案的一小部分,但它可能有所帮助。

编辑:Here是热切加载的RailsCast,有一些文档大约有一半this page