2014-04-12 279 views
1

我對軌道相當陌生,我試圖找出最好的方法來做到這一點。Ruby on Rails嵌套循環

我有一個球員表和一個球隊表。他們都是HABTM彼此並使用連接表。

模型

class Player < ActiveRecord::Base 
    has_and_belongs_to_many :teams 
end 

class Team < ActiveRecord::Base 
    has_and_belongs_to_many :players 
end 

控制器

def players 
    @players = Player.all 
end 

查看

<%@players.each do |player|%> 
    <tr> 
     <td><%= link_to "Add", "steam://friends/add/#{player.steamid}"%></td> 
     <td><%= link_to player.name, player%></td> 
     <td><%=player.email%></td> 
     <td><%=player.teams.teamname%></td> 
    </tr> 
<%end%> 

首先,我知道teamname應該TEAM_NAME。

我試過建立一個循環遍歷團隊,但這個頁面有超過1600個玩家,所以需要幾分鐘來運行它。

我錯過了一個更好的方法來做到這一點?

回答

3

這個速度慢的原因是因爲您正在爲每個用戶執行另一個查詢。這就是所謂的N + 1問題,因爲這是算法的複雜性。

通過更有效地檢索數據庫中的數據很容易解決此問題。你可以告訴Rails使用所謂的Eager Loading加載所有必要的記錄。

在這種情況下,這是因爲這很容易:

@players = Player.includes(:teams).all 

Rails會執行一個查詢中檢索所有玩家,然後執行第二個查詢檢索所有的球隊,你會訪問他們一樣的 - 你的觀點根本不需要改變!

+0

Bam!我知道有一種方法可以加快速度。但是這意味着最好的方法是改變我上面寫的視圖的方式,並把它作爲一個循環放回來,對嗎? – Aarmora

+0

我加了這個'<%​​player.teams.each do | team |放入team.teamname end%>'並且加載sooo的速度要快得多,這非常棒。但我不認爲我的'puts'語法是正確的,因爲它沒有寫任何東西。 – Aarmora

+0

'<%= player.teams.map {| team | team.teamname}%>'這樣的事情就是我需要的,是嗎?這似乎是更好的顯示,但我認爲我需要把它包裝在'原始'。 – Aarmora