Rails - 使用ActiveRecord进行复杂查询

时间:2015-12-09 12:39:02

标签: sql ruby-on-rails activerecord

我有许多复杂的查询要像下面的那样执行。 是否可以(并且值得努力)使用Rails ActiveRecord重写它们?

select a.name as athlete_name, a.nickname, t.name as team_name, top_scorers.goals
from (
  select g.athlete_id, g.team_id, count(*) as goals
  from goal g
  join tournament_edition te on te.tournament_edition_id = g.tournament_edition_id and te.tournament_edition_id = #{tournament_edition_id}
  group by g.athlete_id, g.team_id
  order by count(*) desc
  ) as top_scorers
left join athlete a on a.athlete_id = top_scorers.athlete_id
left join team t on t.team_id = top_scorers.team_id;

如何使用ActiveRecord重写它?

模型结构(遗留数据库):

class Athlete < ActiveRecord::Base
  self.table_name = 'athlete'
  self.primary_key = 'athlete_id'

  has_many :goals
  belongs_to :team
end

class Goal < ActiveRecord::Base
  self.table_name = 'goal'
  self.primary_key = 'goal_id'

  belongs_to :athlete
  belongs_to :team
  belongs_to :tournament_edition
end

class Team < ActiveRecord::Base
  self.table_name = 'team'
  self.primary_key = 'team_id'

  has_many :goals
  has_many :athletes
end

class TournamentEdition < ActiveRecord::Base
  self.table_name = 'tournament_edition'
  self.primary_key = 'tournament_edition_id'

  has_many :goals
end

一个解决方案:

经过多次尝试,我找到了这个“解决方案”。但是我希望在不使用地图解决方法的情况下获取所有信息,以及使用计数的更好方法......

goals = Goal.select(:athlete_id, :team_id, 'count(*) as goals')
            .joins(:tournament_edition)
            .where(tournament_edition: {tournament_edition_id: tournament_edition_id})
            .group(:athlete_id, :team_id)
            .order('goals desc')

goals.map { |goal| 
  {
    name: goal.athlete.name,
    nickname: goal.athlete.nickname,
    team: goal.team.name,
    goals: goal.goals
  }
}

0 个答案:

没有答案