带有has_many的模型中的属性总和:通过关联在Rails 5中不起作用

时间:2018-03-02 14:40:49

标签: ruby-on-rails database model-view-controller has-many-through model-associations

所以我有2个型号。膳食和餐饮。一顿饭可以有多种食物,食物可以是许多膳食的一部分。基本上是一个多对多的关联。我用has_many做了那个:通过,加入的模型叫做MealsFood。创建新餐时,您可以通过复选框选择要添加的食品。食物表有一个名为" calories"饭菜表上有一个名为" 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控制器的create方法中使用它。 请帮忙!在此先感谢:)

3 个答案:

答案 0 :(得分:0)

看起来你实际上并没有使用calc_total_calories做任何事情 - 它没有分配给控制器中的任何内容,也没有将分配给模型中的任何内容。

您可能希望模型方法将其分配给某些内容,如下所示:

def calc_total_calories
    self.total_calories = self.foods.sum(:calories)
end

假设meal模型上的列名为total_calories

这看起来像你在找什么?如果您有任何问题,请告诉我。

答案 1 :(得分:0)

我想,或许,你想要做的事情如下:

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

在原始代码中,您未在total_calories上设置@meal属性,只需调用calc_total_calories方法(可能正确计算总卡路里)。

在SRack提供的答案中,您进行了设置,但从未保存total_calories属性。

update将设置并保存属性。

顺便说一下,您要确保考虑如何处理更改与foods相关联的meal,否则您的total_calories可能会变得陈旧和不正确。< / p>

答案 2 :(得分:0)

您可以在回调中保存后更新总卡路里。

after_save :update_calories

def update_calories
  update_attributes(total_calories: calc_total_calories)
  return true
end