Ruby on Rails - 关联对象的最大数量?

时间:2012-12-12 20:22:51

标签: ruby-on-rails max

我需要查询帮助。我有多个Canteens,每个都有多餐,每顿饭有多个MealPicks。

虽然我不知道这个MealPick模型是不是一个好主意,因为我需要显示今天有多少次选择这顿饭,所以我需要时间戳来进行此查询。

class Meal < ActiveRecord::Base
  def todays_picks
    meal_picks.where(["created_at >= ? AND created_at < ?", Date.today.beginning_of_day, Date.today.end_of_day])
  end
end

之前我在膳食中只有一个meal_picked_count计数器,我用increment_counter方法递增。

好的,现在我需要为每个食堂显示最多MealPicks 的膳食,我在控制台中玩了一遍并尝试了类似Canteen.find(1).meals.maximum("meal_picks.count")的东西,但这显然不起作用因为它不是专栏。

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

你可以这样做:

MealPick.joins(:meal => :canteen)
        .where("canteens.id = ?", 1)
        .order("count_all DESC")
        .group(:meal_id)
        .count

这将返回如下的有序哈希:

{ 200 => 25 }

200将是膳食ID,而25将是计数。

更新

对于任何有兴趣的人,我开始玩这个,看看我是否可以使用ActiveRecord的子查询来提供比我之前提出的有意义的信息。这就是我所拥有的:

class Meal < ActiveRecord::Base
  belongs_to :canteen
  has_many :meal_picks
  attr_accessible :name, :price
  scope :with_grouped_picks, ->() {
    query = <<-QUERY
      INNER JOIN (#{Arel.sql(MealPick.counted_by_meal.to_sql)}) as top_picks 
      ON meals.id = top_picks.meal_id
    QUERY

    joins(query)
  }

  scope :top_picks, with_grouped_picks.order("top_picks.number_of_picks DESC")
  scope :top_pick, top_picks.limit(1)
end

class MealPick < ActiveRecord::Base
  belongs_to :meal
  attr_accessible :user

  scope :counted_by_meal, group(:meal_id).select("meal_id, count(*) as number_of_picks")
  scope :top_picks, counted_by_meal.order("number_of_picks DESC")
  scope :top_pick, counted_by_meal.order("number_of_picks DESC").limit(1)

end

class Canteen < ActiveRecord::Base
  attr_accessible :name
  has_many :meals
  has_many :meal_picks, through: :meals

  def top_picks
    @top_picks ||= meals.top_picks
  end

  def top_pick
    @top_pick ||= top_picks.first
  end
end

这允许我这样做:

c = Canteen.first
c.top_picks #Returns their meals ordered by the number of picks
c.top_pick  #Returns the one with the top number of picks

假设我想根据选秀顺序订购所有餐点。我能做到这一点:

Meal.includes(:canteen).top_picks #Returns all meals for all canteens ordered by number of picks.
Meal.includes(:canteen).where("canteens.id = ?", some_id).top_picks #Top picks for a particular canteen
Meal.includes(:canteen).where("canteens.location = ?", some_location) #Return top picks for a canteens in a given location

由于我们使用的是连接,分组和服务器端计数,因此无需加载整个集合来确定选择计数。这有点灵活,可能更有效率。

答案 1 :(得分:-1)

canteen.meals.max {|m| m.meal_picked_count}