如何在Rails 4 HMT关联中的联接表中保存和更新属性? [英] How do I save and update attributes in a join table in Rails 4 HMT association?
问题描述
我通过配方应用程序的联接表设置具有has_many
,其中Ingredient
和Meal
通过MealIngredient
连接.在MealIngredient
中,我有meal_id
,ingredient_id
和amount
.
I have a has_many
through join table setup for a recipe app where Ingredient
and Meal
connect through MealIngredient
. Within MealIngredient
, I have meal_id
, ingredient_id
, and amount
.
我的问题是:如何保存和更新餐单中的金额栏?
My question is: How can I save and update the amount column in the meal form?
我添加成分的表单字段如下:
My form field for adding an ingredient looks like this:
<% Ingredient.all.each do |ingredient| %>
<label>
<%= check_box_tag "meal[ingredient_ids][]", ingredient.id, f.object.ingredients.include?(ingredient) %>
<%= ingredient.name %>
</label>
<br />
<% end %>
如何保存每种成分的用量?
How do I save the amount for each ingredient?
我引用的是这里的问题:第4条访问联接表属性
I am referencing this question found here: Rails 4 Accessing Join Table Attributes
推荐答案
我为您制作了一个演示: http://meals-test2.herokuapp.com/new
I made a demo for you: http://meals-test2.herokuapp.com/new
-
If you're using a form, you need to use fields_for
and edit it that way:
#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 %>
上面的命令将输出餐食的原料列表 ,并允许您输入金额"值.
The above will output a list of ingredients for the meal and allow you to input the "amount" value.
至于复选框,我必须制作一个演示应用程序以查看是否可以正常运行.如果您认为有必要,我可以这样做.
As for checkboxes, I'd have to make a demo app to see if I can get that working. I can do this if you feel it necessary.
另一种方法是使用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
,从而使您可以通过@meal.ingredients.where(ingredients: {id: "x" }).size
查找金额".您还可以(上文)提出一种简化它的方法.
This way, you'll be able to add as many meals
/ ingredients
as required, allowing you to find the "amount" with @meal.ingredients.where(ingredients: {id: "x" }).size
. You could also make a method to simplify it (above).
您无需为此使用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
关联,因此它为您提供
Because the HABTM record uses the has_many
association in your model, it provides you with the collection_singular_ids
method. This allows you to override the associated data without 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以复制复选框元素.然后,这将允许您向控制器提交 multiple ids
,该控制器将它们盲目地插入到数据库中.
If you wanted to add extra ingredients, you'd need to create JS to duplicate the checkbox element. This will then allow you to submit multiple ids
to the controller, which will just insert them blindly into the db.
此方法覆盖成分列表,并且仅当您对habtm关联/表没有任何唯一性约束时才有效.
This method overrides the ingredients list, and only works if you don't have any uniqueness constraints on the habtm association / table.
这篇关于如何在Rails 4 HMT关联中的联接表中保存和更新属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!