Rails为具有多对多关系的模型创建表单
我有两个模型, Recipe
和Tag
,具有has_and_belongs_to_many
关系。 对于这种关系,我有一个简单的连接表, RecipesTags
。
食谱:
has_and_belongs_to_many :tags
标签:
has_and_belongs_to_many :recipes
现在,在创建新配方时,用户可以以复选框的forms填写配方所属的类别,例如“肉”,“鱼”等。 这些类别实际上只是数据库中的标签。
问题:食谱没有保存任何标签。
配方new
并create
控制器方法:
def new @recipe = Recipe.new @ingredients = Ingredient.all @tags = Tag.all respond_to do |format| format.html # new.html.erb format.json { render json: @recipe } end end # POST /recipes # POST /recipes.json def create @recipe = Recipe.new(params[:recipe]) if (params[:tags]) @recipe.tags << params[:tags] end respond_to do |format| if @recipe.save format.html { redirect_to @recipe, notice: 'Recipe was successfully created.' } format.json { render json: @recipe, status: :created, location: @recipe } else format.html { render action: "new" } format.json { render json: @recipe.errors, status: :unprocessable_entity } end end end
风景:
{:multipart => true}) do |f| %> prohibited this recipe from being saved:
# [ fields that get's saved for the recipe and works fine ]
'btn btn-primary' %>
目前,我收到一条错误消息:未定义方法`merge’为“Meat”:String
“肉”是标签名称。
那么,我在这里做错了什么?
我认为问题是这行@recipe.tags << params[:tags]
。 你用<<
调用的关联方法接受一个对象(在这种情况下期望一个标记对象),但在这种情况下,你似乎可能正在传递一个字符串。
有关更多信息,此链接可能有用http://guides.rubyonrails.org/association_basics.html#has_and_belongs_to_many-association-reference ,特别是在它引用collection<<(object, …)
。
在您的控制器中,您需要执行类似@recipe.tags << tag
,其中tag是特定的标记对象。
所以,试试这个:
在你的控制器中
params[:tags].each do |k,v| @recipe.tags << Tag.find(k) end
在你看来
<% @tags.each do |t| %> <%= f.label t.name %> <%= f.check_box "tags[#{t.id}]" %>
<% end %>
试试这个:
def create @recipe = Recipe.new(params[:recipe]) params[:tags].each do |tag| @recipe.tags << Tag.find_by_name(tag) end respond_to do |format| if @recipe.save format.html { redirect_to @recipe, notice: 'Recipe was successfully created.' } format.json { render json: @recipe, status: :created, location: @recipe } else format.html { render action: "new" } format.json { render json: @recipe.errors, status: :unprocessable_entity } end end end
在视图中:
<% @tags.each do |t| %> <%= label_tag t.name %> <%= check_box_tag "tags[#{t.name}]", t.name %>
<% end %>