2014-04-12 233 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