I made a demo for you: http://meals-test2.herokuapp.com/new http://meals-test2.herokuapp.com/new
--
如果您使用的是表单,则需要使用fields_for http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-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 %>
上面会输出一个成分列表为了吃饭并允许您输入“金额”值。
至于复选框,我必须制作一个演示应用程序来看看是否可以正常工作。如果你觉得有必要的话我可以做。
另一种方法是与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
。您还可以制定一种方法来简化它(如上所述)。
你不需要使用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 http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many方法。这允许您覆盖关联的数据,而无需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
到控制器,控制器只会将它们盲目地插入到数据库中。
这个方法覆盖成分列表,并且仅当您对 habtm 关联/表没有任何唯一性约束时才有效。