重构rails调用数据库

时间:2013-10-26 17:32:05

标签: sql ruby-on-rails ruby database rails-activerecord

如何重构此代码段以最大限度地减少对数据库的调用次数?

/Player.rb

def num_matchups
    this_week_appearances = 0
    this_week_appearances += Matchup.where(player_1: self.id).sum("pts_player_1")
    this_week_appearances += Matchup.where(player_1: self.id).sum("pts_player_2")
    this_week_appearances += Matchup.where(player_2: self.id).sum("pts_player_1")
    this_week_appearances += Matchup.where(player_2: self.id).sum("pts_player_2")
end

目标是找到玩家(无论哪个玩家被召唤)在投票的比赛中的次数。玩家本可以参加Matchup.player_1Matchup.player_2领域的比赛(没有任何区别),因为我不关心他们是赢还是输(只是出场次数) ,我需要比赛中两位球员的得分。

我想它会看起来像这样,但我不知道它应该使用的语法:

this_week_appearances = Matchup.where(player_1: self.id OR player_2: self.id).sum("pts_player_1").sum("pts_player_2")

可以这样做吗?

1 个答案:

答案 0 :(得分:2)

您希望找到Matchupplayer_1player_2的所有self.id,然后求和pts_player_1pts_player_2对于那些Matchup。 “player_1player_2部分很容易一次完成:

Matchup.where('player_1 = :id or player_2 = :id', :id => self.id)

但你怎么总结这些分数?好吧,您可以将任何SQL表达式传递给sum,这样您就可以:

Matchup.where('player_1 = :id or player_2 = :id', :id => self.id)
       .sum('pts_player_1 + pts_player_2')

您可能遇到的一个问题是ActiveRecord不够聪明,不知道pts_player_1 + pts_player_2是一个数字,但是to_i调用应该排除这一点:

Matchup.where('player_1 = :id or player_2 = :id', :id => self.id)
       .sum('pts_player_1 + pts_player_2')
       .to_i

以上假设您在pts_player_1pts_player_2中不会有任何NULL。