我试图在视图中列出我的所有棒球运动员及其基本信息。大部分信息都位于 Players 表中。但是,我也试图拉出他们的位置,这是另一个名为位置的表格中的一列。 Players表与此Positions表没有直接关联。但是,玩家和位置都有一个has_many和belongs_to与另一个名为 GameStats 的表关联,该表包含该游戏的所有玩家统计数据,包括所扮演的位置。这是我的表格:
TABLES
Player Table
id | fname | lname
---+-------+-------
1 | Joe | Smith
2 | Fred | Jones
GameStat Table
player_id | position_id
----------+-------------
1 | 7
1 | 7
1 | 8
1 | 8
2 | 9
2 | 9
2 | 9
2 | 9
Position Table
id | position
---+---------
7 | LF
8 | CF
9 | RF
我试图加入这三张桌子,但我没有得到我想要的。这是我的疑问:
@position_players = BatterGameStat
.select("player_id, players.fname || ' ' || players.lname AS name, players.bats AS bats, players.throws AS throws, position_id, array_agg(positions.position) AS pos")
.group("batter_game_stats.player_id, batter_game_stats.position_id, fname, lname, bats, throws, position")
.joins(:player, :position)
.order(:lname)
基本上,我会返回一个列表,但如果他们在不同游戏中扮演不同的位置,则会使用以下视图代码为每个唯一位置多次列出:
<% @position_players.each do |pp| %>
<tr class="player">
<td><%= link_to(pp.name, player_path(pp.player_id)) %></td>
<td><%= pp.pos %></td>
<td><%= pp.bats %></td>
<td><%= pp.throws %></td>
</tr>
<% end %>
以下是我想要归还的内容以及我得到的内容:
Desired returned html table:
Player | Position(s)
-----------+-------------
Joe Smith | LF, CF
Fred Jones | RF
This is what I'm actually getting:
Player | Position(s)
-----------+-------------
Joe Smith | LF
Joe Smith | CF
Fred Jones | RF
答案 0 :(得分:0)
您正在遍历位置播放器,这就是为什么您的HTML表与您的gamestats
表基本相同的原因。我相信我有一个可以帮助你的解决方案。首先,您应该为has_many :through
和Player
模型添加Position
关联。我还会在name
模型中添加Player
函数,因为您在查询中生成了它,您真的不应该这样做。
class Player < ActiveRecord::Base
has_many :game_stats
has_many :positions, through: :game_stats, uniq: true
def name
self.fname + ' ' + self.lname
end
end
class Position < ActiveRecord::Base
has_many :game_stats
has_many :players, through: game_stats
end
有关关联的更多信息(我建议您阅读),请参阅Rails Guide to Associations。通过此更改,您可以极大地简化查询。
@players = Player.all
你想要的是球员,而不是联赛桌。您很少想要实际使用此特定连接模型,因为您没有任何其他列。您可以做的最后一件事是更改您的视图,如下所示:
<% @players.find_each do |p| %>
<tr class="player">
<td><%= link_to(p.name, player_path(pp.player_id)) %></td>
<td><%= p.positions.join(", ") %></td>
<td><%= p.bats %></td>
<td><%= p.throws %></td>
</tr>
<% end %>
这应该为您提供解决问题所需的一切。你应该仔细阅读所有Rails Guides,因为它们会帮助你极大地帮助你。当我开始时,他们肯定帮了我。
答案 1 :(得分:0)
您的问题是,您正在滥用GROUP BY position
为每个人生成一组不同的position
,并且与您的&#34; GROUP BY冲突以进行汇总&#34; 。在GROUP BY列表中加入position
会将('Joe Smith', array['LF'])
和('Joe Smith', array['CF'])
分成不同的行(即单独的组)。
您可以将distinct
投入array_agg
并将其从GROUP BY中删除。您想要的SQL如下所示:
select pl.id,
pl.fname || ' ' || pl.lname as name,
array_agg(distinct pos.position)
from players pl
join game_stats gs on pl.id = gs.player_id
join positions pos on gs.position_id = pos.id
group by pl.id, pl.fname, pl.lname
order by pl.lname
演示:http://sqlfiddle.com/#!15/ac83e/3
ActiveRecord版本如下所示:
@position_players = BatterGameStat
.select("player_id, players.fname || ' ' || players.lname AS name, array_agg(distinct positions.position) AS pos")
.group("player_id, fname, lname")
.joins(:player, :position)
.order(:lname)
我建议您在视图中格式化数组时更明确一点:
<%= pp.pos.join(', ') %>