预加载嵌套关联

Eager Loading Nested Association

我有以下型号:

class Session < ActiveRecord::Base
  belongs_to :game

  has_many :session_players
  has_many :players, through: :session_players
end

class SessionPlayer < ActiveRecord::Base
  belongs_to :player
  belongs_to :session
end

class Player < ActiveRecord::Base
  has_many :session_players
  has_many :sessions, through: :session_player
end

在 erb 文件中,我试图遍历所有会话,显示有关会话的一些信息并显示有关该会话的每个玩家的嵌套数据。

erb文件中的相关代码为:

<% @sessions.each do |session| %>
      <tr>
        <td><%= session.name %></td>
        <td>
          <table>
            <% session.session_players.each do |session_player| %>
                <!-- problem line below -->
                <tr><td><%= session_player.player.name %> (<%= session_player.placing %>)</td></tr>
            <% end %>
          </table>
        </td>
      </tr>
<% end %>

问题是,在从 session_player.player.name 调用中获取 name 值时,由于空异常,我无法同时从播放器和 session_player 对象中提取数据。调用 session_player.placing 成功。

我认为这是一个延迟加载问题,因为我可以在调试代码时检索 session_player.player.name 的值,而不是在 运行 时。我尝试通过在控制器中尝试各种包含组合来急切地加载数据,但没有任何区别:

@sessions = Session.includes(:session_players => :player).all

这个怎么样:

@sessions = Session.joins(:session_players)

或者避免N+1

@sessions = Session.includes(:session_players)

你可以用try来定义什么时候没有关系

<% session.session_players.each do |session_player| %>
   <!-- problem line below -->
   <tr><td><%= session_player.try(:player).try(:name) %> (<%= session_player.placing %>)</td></tr>
<% end %>

代码是正确的,但我用来填充它的数据不正确。其中一个值稍后在数据列表中为空。直到在模板渲染期间访问数据时才发现这一点。预加载对异常发生时的数据没有影响。