2010-08-27 75 views
4

Rails 3問題。 我的食品具有以下屬性的食物表:使用Rails計算組查詢3

  • 名(每克)(每克)
  • 碳水化合物(每克)
  • 蛋白
  • 脂肪
  • 卡路里(每克)

然後,我有一個LoggedFoods表,表示食物在給定時間已被吃掉。它具有以下屬性:

  • food_id
  • number_of_grams_eaten
  • ate_when(日期時間)

所以我的問題是,我想獲得的卡路里總數,脂肪,蛋白質,每天消耗的碳水化合物(全天)。我一直在嘗試使用新的ActiveRecord查詢接口來完成這個Rails 3,但沒有運氣。有任何想法嗎?

回答

12

這裏有一個快速的第一遍,可能有一些錯誤,但數字看起來一目瞭然。也:我只測試此上sqlite3的,等等其他數據庫的結果可以是不同的(在情況下,SUM或組功能是不同的)

app/models/logged_food.rb

class LoggedFood < ActiveRecord::Base 
    belongs_to :food 

    def self.totals_by_day(date) 
    start_time = Time.parse(date).beginning_of_day 
    end_time = Time.parse(date).end_of_day 

    t = LoggedFood.arel_table 

    totals = LoggedFood. 
     where(t[:ate_when].gteq(start_time)). 
     where(t[:ate_when].lteq(end_time)). 
     joins(:food). 
     select("SUM(calories * grams_eaten) as total_calories"). 
     select("SUM(fat * grams_eaten) as total_fat"). 
     select("SUM(carbs * grams_eaten) as total_carbs"). 
     select("SUM(protien * grams_eaten) as total_protien") 

    return nil if totals.empty? 

    { 
     :total_calories => totals.first.total_calories, 
     :total_fat => totals.first.total_fat, 
     :total_carbs => totals.first.total_carbs, 
     :total_protien => totals.first.total_protien 
    } 

    end 

end 

db/seeds.rb(I明顯地不具備的營養的想法食品的信息)

@pizza = Food.create(:name => "pizza", :calories => 500, :fat => 10, :carbs => 20, :protien => 30) 
@hot_dog = Food.create(:name => "hot dog", :calories => 400, :fat => 10, :carbs => 20, :protien => 30) 
@apple = Food.create(:name => "apple", :calories => 100, :fat => 1, :carbs => 2, :protien => 3) 
@banana = Food.create(:name => "banana", :calories => 100, :fat => 2, :carbs => 4, :protien => 6) 

LoggedFood.create(:food_id => @pizza.id, :grams_eaten => 10, :ate_when => Time.now) 
LoggedFood.create(:food_id => @apple.id, :grams_eaten => 10, :ate_when => Time.now) 
LoggedFood.create(:food_id => @banana.id, :grams_eaten => 10, :ate_when => 12.hours.ago) 
LoggedFood.create(:food_id => @apple.id, :grams_eaten => 10, :ate_when => 1.day.ago) 
LoggedFood.create(:food_id => @pizza.id, :grams_eaten => 10, :ate_when => 2.days.ago) 
LoggedFood.create(:food_id => @banana.id, :grams_eaten => 10, :ate_when => 36.hours.ago) 
LoggedFood.create(:food_id => @hot_dog.id, :grams_eaten => 10, :ate_when => 2.days.ago) 
LoggedFood.create(:food_id => @banana.id, :grams_eaten => 10, :ate_when => 50.hours.ago) 

然後在控制檯:

ree-1.8.7-2010.02 > LoggedFood.totals_by_day("2010-08-27") 
    LoggedFood Load (0.2ms) SELECT SUM(calories * grams_eaten) as total_calories, SUM(fat * grams_eaten) as total_fat, SUM(carbs * grams_eaten) as total_carbs, SUM(protien * grams_eaten) as total_protien FROM "logged_foods" INNER JOIN "foods" ON "foods"."id" = "logged_foods"."food_id" WHERE ("logged_foods"."ate_when" >= '2010-08-27 04:00:00.000000') AND ("logged_foods"."ate_when" <= '2010-08-28 03:59:59.999999') LIMIT 1 
=> {:total_fat=>130, :total_protien=>390, :total_calories=>7000, :total_carbs=>260} 

ree-1.8.7-2010.02 > LoggedFood.totals_by_day("2010-08-26") 
    LoggedFood Load (0.3ms) SELECT SUM(calories * grams_eaten) as total_calories, SUM(fat * grams_eaten) as total_fat, SUM(carbs * grams_eaten) as total_carbs, SUM(protien * grams_eaten) as total_protien FROM "logged_foods" INNER JOIN "foods" ON "foods"."id" = "logged_foods"."food_id" WHERE ("logged_foods"."ate_when" >= '2010-08-26 04:00:00.000000') AND ("logged_foods"."ate_when" <= '2010-08-27 03:59:59.999999') LIMIT 1 
=> {:total_fat=>30, :total_protien=>90, :total_calories=>2000, :total_carbs=>60}