如何保存和更新 table in Rails 4 HMT 关联中的属性?

How do I save and update attributes in a join table in Rails 4 HMT association?

我有一个 has_many 通过加入 table 设置的食谱应用程序,其中 IngredientMeal 通过 MealIngredient 连接。在 MealIngredient 内,我有 meal_idingredient_idamount

我的问题是:如何保存和更新膳食表格中的金额栏?

我用于添加成分的表单字段如下所示:

<% Ingredient.all.each do |ingredient| %>
  <label>
    <%= check_box_tag "meal[ingredient_ids][]", ingredient.id, f.object.ingredients.include?(ingredient) %>
    <%= ingredient.name %>
  </label>
  <br />
<% end %>

如何保存每种成分的数量?

我引用的是在这里找到的这个问题:Rails 4 Accessing Join Table Attributes

我为你做了一个演示:http://meals-test2.herokuapp.com/new

--

如果您使用的是表格,则需要使用 fields_for 并以这种方式进行编辑:

#app/controllers/meals_controller.rb
class MealsController < ApplicationController
  def edit
    @meal = Meal.find params[:id]
  end

  private

  def meal_params
    params.require(:meal).permit(meal_ingredient_attributes: [:amount])
  end
end

#app/views/meals/edit.html.erb
<%= form_for @meal do |f| %>
  <%= fields_for :meal_ingredients do |i| %>
      <%= f.object.ingredient.name #-> meal_ingredient belongs_to ingredient %>
      <%= i.number_field :amount %>
  <% end %>
  <%= f.submit %>
<% end %>

以上将输出餐点 的成分列表 并允许您输入 "amount" 值。

至于复选框,我必须制作一个演示应用程序,看看我是否可以让它工作。如果你觉得有必要,我可以做。


另一种方法是 has_and_belongs_to_many:

#app/models/meal.rb
class Meal < ActiveRecord::Base
  has_and_belongs_to_many :ingredients do
     def amount #-> @meal.ingredients.first.amount
        ...........
     end
  end
end

#app/models/ingredient.rb
class Ingredient < ActiveRecord::Base
  has_and_belongs_to_many :meals
end

这样,您就可以根据需要添加任意数量的 meals / ingredients,这样您就可以找到 "amount" 和 @meal.ingredients.where(ingredients: {id: "x" }).size。你也可以做一个方法来简化它(上面)。

你不需要为此使用 fields_for:

#app/controllers/meals_controller.rb
class MealsController < ApplicationController
  def new
     @meal = Meal.new
  end
  def edit
     @meal = Meal.find params[:id]
  end

  def update
     @meal = Meal.find params[:id]
     @meal.save
  end

  def create
     @meal = Meal.new meal_params
     @meal.save
  end

  private

  def meal_params
    params.require(:meal).permit(ingredient_ids: [])
  end
end

因为HABTM记录在你的模型中使用了has_many关联,它为你提供了collection_singular_ids方法。这允许您在没有 fields_for:

的情况下覆盖关联数据
#app/views/meals/new.html.erb
<%= form_for @meal do |f| %>
  <%= f.collection_check_boxes :ingredient_ids, Ingredient.all, :id, :name %>
  <%= f.submit %>
<% end %>

如果你想添加额外的成分,你需要创建 JS 来复制复选框元素。然后,这将允许您将 多个 ids 提交给控制器,它只会盲目地将它们插入数据库。

此方法覆盖成分列表,并且仅在您对 habtm 关联/table.

没有任何唯一性约束时才有效