具有 has_many 的模型中的属性总和:通过关联在 Rails 5 中不起作用
Sum of attributes in model with has_many :through association not working in Rails 5
所以我有 2 个模型。膳食和食品。一顿饭可以有多种食物,一种食物可以是多餐的一部分。基本上是一个多对多的关联。我用 has_many :through 做到了这一点,加入模型称为 MealsFood。创建新餐时,您可以通过复选框选择要添加的食物。 foods table 有一个名为 "calories" 的列,而 meals table 有一个名为 "total_calories" 的列,它计算膳食中所有食品的总和。
问题是它不工作。
这是我目前所拥有的...
型号
class Meal < ApplicationRecord
belongs_to :user, optional: true
has_many :meal_foods
has_many :foods, through: :meal_foods
def calc_total_calories
self.foods.sum(:calories)
end
end
class MealFood < ApplicationRecord
belongs_to :meal
belongs_to :food
end
class Food < ApplicationRecord
has_many :meal_foods
has_many :meals, through: :meal_foods
end
膳食控制器
class MealsController < ApplicationController
def index
end
def new
@meal = Meal.new
end
def create
@meal = Meal.new(meal_params)
@meal.calc_total_calories
if @meal.save
redirect_to @meal
else
redirect_to root_path
end
end
private
def meal_params
params.require(:meal).permit(:user_id, :meal_type, :date,
:total_calories, :total_carbohydrates, :total_fat, food_ids:[])
end
end
查看(用餐新动作)
<%= form_for(@meal) do |f| %>
<div class="field">
<%= f.label :meal_type %>
<%= f.select :meal_type, ["Breakfast", "Lunch", "Dinner", "Morning Snack", "Afternoon Snack, Evening Snack"] %>
</div>
<div class="field">
<% Food.all.each do |food| %>
<%= check_box_tag "meal[food_ids][]", food.id %>
<%= food.name %>
<% end %>
</div>
<div class="field">
<%= f.submit class: "button button-highlight button-block" %>
</div>
<% end %>
注意膳食模型中的 def calc_total_calories。这是我用来计算卡路里的方法,但它不起作用。我在 Meals 控制器的创建方法中使用它。
请帮忙!提前致谢:)
看起来你实际上并没有用 calc_total_calories
做任何事情 - 它没有分配给控制器中的任何东西,也没有分配给 到 中的任何东西型号。
您可能希望模型方法将其分配给某些东西,如下所示:
def calc_total_calories
self.total_calories = self.foods.sum(:calories)
end
假定您的 meal
模型中有一列名为 total_calories
。
这看起来像您要找的东西吗?如果您有任何问题,请告诉我。
我在想,也许你想做这样的事情:
class MealsController < ApplicationController
def index
end
def new
@meal = Meal.new
end
def create
@meal = Meal.new(meal_params)
if @meal.save
@meal.update(total_calories: @meal.calc_total_calories)
redirect_to @meal
else
redirect_to root_path
end
end
private
def meal_params
params.require(:meal).permit(:user_id, :meal_type, :date, :total_calories, :total_carbohydrates, :total_fat, food_ids:[])
end
end
在您的原始代码中,您没有在 @meal
上设置 total_calories
属性,只是调用 calc_total_calories
方法(这可能正确计算了总卡路里)。
在 SRack 提供的答案中,您正在设置,但从未保存 total_calories
属性。
update
将同时设置和保存属性。
顺便说一句,您一定要考虑如何处理与 meal
关联的 foods
的更改,否则您的 total_calories
可能会变得陈旧和不正确。
您可以在保存后在回调中更新总卡路里。
after_save :update_calories
def update_calories
update_attributes(total_calories: calc_total_calories)
return true
end
所以我有 2 个模型。膳食和食品。一顿饭可以有多种食物,一种食物可以是多餐的一部分。基本上是一个多对多的关联。我用 has_many :through 做到了这一点,加入模型称为 MealsFood。创建新餐时,您可以通过复选框选择要添加的食物。 foods table 有一个名为 "calories" 的列,而 meals table 有一个名为 "total_calories" 的列,它计算膳食中所有食品的总和。 问题是它不工作。
这是我目前所拥有的...
型号
class Meal < ApplicationRecord
belongs_to :user, optional: true
has_many :meal_foods
has_many :foods, through: :meal_foods
def calc_total_calories
self.foods.sum(:calories)
end
end
class MealFood < ApplicationRecord
belongs_to :meal
belongs_to :food
end
class Food < ApplicationRecord
has_many :meal_foods
has_many :meals, through: :meal_foods
end
膳食控制器
class MealsController < ApplicationController
def index
end
def new
@meal = Meal.new
end
def create
@meal = Meal.new(meal_params)
@meal.calc_total_calories
if @meal.save
redirect_to @meal
else
redirect_to root_path
end
end
private
def meal_params
params.require(:meal).permit(:user_id, :meal_type, :date,
:total_calories, :total_carbohydrates, :total_fat, food_ids:[])
end
end
查看(用餐新动作)
<%= form_for(@meal) do |f| %>
<div class="field">
<%= f.label :meal_type %>
<%= f.select :meal_type, ["Breakfast", "Lunch", "Dinner", "Morning Snack", "Afternoon Snack, Evening Snack"] %>
</div>
<div class="field">
<% Food.all.each do |food| %>
<%= check_box_tag "meal[food_ids][]", food.id %>
<%= food.name %>
<% end %>
</div>
<div class="field">
<%= f.submit class: "button button-highlight button-block" %>
</div>
<% end %>
注意膳食模型中的 def calc_total_calories。这是我用来计算卡路里的方法,但它不起作用。我在 Meals 控制器的创建方法中使用它。 请帮忙!提前致谢:)
看起来你实际上并没有用 calc_total_calories
做任何事情 - 它没有分配给控制器中的任何东西,也没有分配给 到 中的任何东西型号。
您可能希望模型方法将其分配给某些东西,如下所示:
def calc_total_calories
self.total_calories = self.foods.sum(:calories)
end
假定您的 meal
模型中有一列名为 total_calories
。
这看起来像您要找的东西吗?如果您有任何问题,请告诉我。
我在想,也许你想做这样的事情:
class MealsController < ApplicationController
def index
end
def new
@meal = Meal.new
end
def create
@meal = Meal.new(meal_params)
if @meal.save
@meal.update(total_calories: @meal.calc_total_calories)
redirect_to @meal
else
redirect_to root_path
end
end
private
def meal_params
params.require(:meal).permit(:user_id, :meal_type, :date, :total_calories, :total_carbohydrates, :total_fat, food_ids:[])
end
end
在您的原始代码中,您没有在 @meal
上设置 total_calories
属性,只是调用 calc_total_calories
方法(这可能正确计算了总卡路里)。
在 SRack 提供的答案中,您正在设置,但从未保存 total_calories
属性。
update
将同时设置和保存属性。
顺便说一句,您一定要考虑如何处理与 meal
关联的 foods
的更改,否则您的 total_calories
可能会变得陈旧和不正确。
您可以在保存后在回调中更新总卡路里。
after_save :update_calories
def update_calories
update_attributes(total_calories: calc_total_calories)
return true
end