SQL / ActiveRecord:基于条件限制记录

时间:2014-09-09 22:33:22

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

该数据库由3个模型组成:Level,World和Score。

class World < ActiveRecord::Base
  has_many :levels
  has_many :scores, through: :levels
end

class Level < ActiveRecord::Base
  belongs_to :world
  has_many :scores
end

class Score < ActiveRecord::Base
  belongs_to :level
  has_one :world, through: :level

  scope :top, -> n { limit(n).order(points: :desc) }
end

可以获得一个级别的前5个分数:level.scores.top(5)。现在,客户希望看到一个特定世界的每个级别的前5个分数。显然,world.scores.top(5)不会起作用。对于如何获得世界上每个级别的前5个分数,是否有一个干净的解决方案?

最终的对象最好是ActiveRecord :: Collection!例如,不足以满足以下要求:world.levels.map { |l| l.scores.top(5) }.flatten。将Score.includes(:level).where(levels: { world_id: x })作为一开始而不是反过来也是有益的,除非这是不可能的。

虽然我更喜欢全球解决方案,但我也可以接受仅限MySQL的解决方案。

提前致谢,
Danyel。

1 个答案:

答案 0 :(得分:0)

经过对各个站点的一些研究并得到了队友的大量帮助,我们最终确实找到了一个可以轻松纳入rails的解决方案。以下查询将获得每个级别的level_group的最高n分数。

sub_query = Highscore.from("highscores s2").where("s2.level_id = levels.id").where(
  "s2.points > highscores.points"
).select("COUNT(*)").to_sql
Highscore.include(:level).where(levels: { level_group_id: id }).where("( #{sub_query} ) < ?", n)