我需要查询方面的帮助。我有多个食堂,每个食堂有多个餐点,每餐有多个 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
Run Code Online (Sandbox Code Playgroud)
在我在 Meal 中只有一个 meal_picked_count 计数器之前,我通过 increment_counter 方法增加了它。
好的,现在我需要为每个 Canteen 显示 MealPicks 最多的 Meal,我在控制台中玩弄并尝试了类似的东西,Canteen.find(1).meals.maximum("meal_picks.count")但这显然不起作用,因为它不是一个列。
有任何想法吗?
你可以这样做:
MealPick.joins(:meal => :canteen)
.where("canteens.id = ?", 1)
.order("count_all DESC")
.group(:meal_id)
.count
Run Code Online (Sandbox Code Playgroud)
这将返回一个有序的散列,如下所示:
{ 200 => 25 }
Run Code Online (Sandbox Code Playgroud)
在哪里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
Run Code Online (Sandbox Code Playgroud)
这允许我这样做:
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
Run Code Online (Sandbox Code Playgroud)
假设我想按选择的数量订购所有餐点。我可以这样做:
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
Run Code Online (Sandbox Code Playgroud)
由于我们使用连接、分组和服务器端计数,因此不需要加载整个集合来确定选择计数。这更灵活,可能更有效。
| 归档时间: |
|
| 查看次数: |
3247 次 |
| 最近记录: |