2015-09-25 76 views
0

我有以下型號:預先加載嵌套協會

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文件中的相關代碼:

<% @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 %> 

的問題是,獲得name值關閉的時候,我不能拉過兩個玩家和session_player對象的數據由於空例外致電session_player.player.name。撥打session_player.placing成功。

我認爲這是一個延遲加載問題,因爲我可以在調試代碼時檢索session_player.player.name的值,而不是在運行代碼時。我想急於通過嘗試各種包括控制器組合加載數據,但它並沒有區別:

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

+1

當從'session_player.player.name'獲得名稱值時,你得到空例外的原因是因爲特定的'session_player'沒有與其相關的'player'。確保'session_players'表中'player_id'字段的所有值都是**不爲空**並且與'players'表的'ids'匹配 – Pavan

+0

這就是問題所在。其中一個較晚的值爲null。我認爲急切的加載會在控制器中發現問題,而不是解決模板中的數據問題,但事實並非如此。 –

回答

0

該代碼是正確的,但我填寫的數據不是。其中一個值在數據列表後面爲null。直到在模板呈現過程中訪問數據時纔會捕獲這些數據。當發生異常時,緊急加載對數據的時間沒有影響。

0

如何:

@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 %>