如何在has_many中获取模型的属性:通过Rails 5中的关联

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在has_many中获取模型的属性:通过Rails 5中的关联相关的知识,希望对你有一定的参考价值。

所以我在has_many中有两个模型:通过关联。这两种模式是膳食和食物。基本上,膳食可以有多种食物,食物可以是许多膳食的一部分。第三个连接模型称为meal_foods。我已将其设置为当您创建新膳食时,您可以通过复选框选择所有食物的食物。食品具有卡路里和蛋白质等属性,膳食具有total_calories和total_proteins等属性。我怎样才能做到这一点,以便在制作新餐时我可以计算所有食品的所有属性(卡路里,蛋白质等)的值?

到目前为止,这是我的代码:

楷模

class Meal < ApplicationRecord
    belongs_to :user, optional: true
    has_many :meal_foods
    has_many :foods, through: :meal_foods
end

class Food < ApplicationRecord
    has_many :meal_foods
    has_many :meals, through: :meal_foods
end

class MealFood < ApplicationRecord
    belongs_to :meal
    belongs_to :food
end

膳食控制器

    def create
        @meal = Meal.new(meal_params)
        @meal.user_id = current_user.id

        @meal.total_calories = #Implement code here...

        if @meal.save
            redirect_to @meal
        else
            redirect_to root_path
        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 %>

提前致谢!

答案

您可以使用sum例如卡路里:

class Meal < ApplicationRecord
    belongs_to :user, optional: true
    has_many :meal_foods
    has_many :foods, through: :meal_foods

    def total_calories
      foods.sum(:calories)
    end
end

Sum适用于关联中的任何数字列。

如果对于某些人你需要将值存储在数据库中(例如,你将根据卡路里含量对膳食进行分类并且更容易存储该值),那么你可以告诉用餐它在创建时应该计算并储存卡路里,例如:

class Meal < ApplicationRecord
    belongs_to :user, optional: true
    has_many :meal_foods
    has_many :foods, through: :meal_foods

    # Tells rails to run this method when each Meal is first created
    after_create :store_total_calories

    # actually calculates the number of calories for any given meal (can be used even after saving in the db eg if the calories changed)
    def calculate_total_calories
      foods.sum(:calories)
    end

    # calculates, then resaves the updated value   
    def store_total_calories
       update(total_calories: calculate_total_calories)
    end
end

注意:更多关于after_create callback here

注意:在控制器中不需要为所有Just Work完成任何操作。

以上是关于如何在has_many中获取模型的属性:通过Rails 5中的关联的主要内容,如果未能解决你的问题,请参考以下文章

Ecto - 如何通过特定查询获取“has_many”

Rails has_many :通过连接模型中的额外属性查找

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

如何通过“has_many”关联获取数据?

如何通过关联在 has_many 中使用回调?

如何实现 has_many :through 关联两种方式?