Rails对多对多嵌套形式:如何防止重复? [英] Rails nested form on many-to-many: how to prevent duplicates?

查看:67
本文介绍了Rails对多对多嵌套形式:如何防止重复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在Rails 3.2.3应用程序中设置了一个嵌套表单,它可以正常工作,我的模型是:

I've setup a nested form in my rails 3.2.3 app, it's working fine, my models are:

class Recipe < ActiveRecord::Base
  attr_accessible :title, :description, :excerpt, :date, :ingredient_lines_attributes

  has_and_belongs_to_many :ingredient_lines
  accepts_nested_attributes_for :ingredient_lines
end

和:

class IngredientLine < ActiveRecord::Base
  attr_accessible :ingredient_id, :measurement_unit_id, :quantity

  has_and_belongs_to_many :recipes
  belongs_to :measurement_unit
  belongs_to :ingredient
end

如上所述,一个配方可以有多个成分行,反之亦然.

As above, a Recipe can have multiple IngredientLines and vice versa.

我要避免的是IngredienLine表上的记录重复.

What I'm trying to avoid is record duplication on IngredienLine table.

例如,假设对于配方_1,具有{"measurement_unit_id" => 1,"ingredient_id" => 1,"quantity" => 3.5}的IngredientLine是关联的,如果对于recipe_5,IngredientLine子窗体由用户使用相同的值,我不希望在IngredientLine表上有新记录,而只希望联接表Ingredient_lines_recipes中有新的关联记录.

For example imagine that for recipe_1 an IngredientLine with {"measurement_unit_id" => 1, "ingredient_id" => 1, "quantity" => 3.5} is associated, if for recipe_5 the IngredientLine child form is compiled by the user with the same values, I don't want a new record on IngredientLine table, but only a new association record in the join table ingredient_lines_recipes.

请注意,当前我没有任何IngredientLine控制器,因为保存和更新IngredientLines是由嵌套表单例程处理的.甚至我的Recipe控制器都是普通的和标准的:

Note that currently I dont't have any IngredientLine controller as saving and updating IngredientLines is handled by nested form routines. Even my Recipe controller is plain and standard:

class RecipesController < ApplicationController
  respond_to :html

  def new
    @recipe = Recipe.new
  end

  def create
    @recipe = Recipe.new(params[:recipe])
    flash[:notice] = 'Recipe saved.' if @recipe.save  
    respond_with(@recipe)
  end

  def destroy
    @recipe = Recipe.find(params[:id])
    @recipe.destroy
    respond_with(:recipes)
  end

  def edit
    respond_with(@recipe = Recipe.find(params[:id]))
  end

  def update
    @recipe = Recipe.find(params[:id])
    flash[:notice] = 'Recipe updated.' if @recipe.update_attributes(params[:recipe])
    respond_with(@recipe)
  end

end

我的猜测是,应该足以用find_or_create替代IngredientLine的标准create行为,但是我不知道如何实现.

My guess is that should be enough to override the standard create behavior for IngredientLine with find_or_create, but I don't know how to achieve it.

但是还有一个重要的注意事项,想象一下在子窗体中存在一些IngredientsLines的编辑,如果我添加了另一个已经存储在IngredientLine表中的IngredientLine,则rails当然不应在IngredientLine表上写任何东西,但是还应该区分已经与父级关联的子记录,以及需要为其创建关系并在联接表上写入新记录的新子记录.

But there's another important point to take care, imagine the edit of a child form where some IngredientLines are present, if I add another IngredientLine, which is already stored in IngredientLine table, rails of course should not write anything on IngredientLine table, but should also distinguish between child records already associated to the parent, and the new child record for which needs to create the relation, writing a new record on the join table.

谢谢!

推荐答案

旧问题,但我遇到了同样的问题.忘记将:id添加到带有4个strong_parameters的白名单中.

Old question but I had the same problem. Forgot to add :id to white list with rails 4 strong_parameters.

例如:

widgets_controller.rb

widgets_controller.rb

def widget_params
  params.require(:widget).permit(:name, :foos_attributes => [:id, :name, :_destroy],)
end

widget.rb

widget.rb

class Widget < ActiveRecord::Base
  has_many :foos, dependent: :destroy
  accepts_nested_attributes_for :foos, allow_destroy: true
end

foo.rb

class Foo < ActiveRecord::Base
  belongs_to :widget
end

这篇关于Rails对多对多嵌套形式:如何防止重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆