Rails的许多一对多的嵌套形式:如何防止重复?(Rails nested form on many

2019-09-17 10:16发布

我设置的嵌套形式,我的Rails 3.2.3应用程序,它的正常工作,我的型号有:

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

如上所述,一配方可以有多个IngredientLines,反之亦然。

我试图避免是IngredienLine表记录重复。

例如设想为配方1的IngredientLine与{“measurement_unit_id” => 1“ ingredient_id” => 1,“数量” => 3.5}相关联,如果recipe_5的IngredientLine子形式是由用户使用相同的值编译,我不想在连接表ingredient_lines_recipes上IngredientLine表的新记录,但只有一个新的关联记录。

请注意,目前我dont't有任何IngredientLine控制器作为保存和更新IngredientLines被嵌套表格程序处理。 即使我的食谱控制器平原和标准:

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

我的猜测是,应该足以覆盖标准create了IngredientLine行为与find_or_create ,但我不知道如何去实现它。

但有照顾,想象一个孩子形式,其中一些IngredientLines都存在,如果我再添IngredientLine,已经被存储在IngredientLine表,当然导轨不应该写上IngredientLine表什么的编辑另一个重要的一点,但也应已经关联到父子记录,并于需要创建关系的新的子记录区分,联结表中书写新的纪录。

谢谢!

Answer 1:

在配方重新定义模型方法

def ingredient_lines_attributes=(attributes)
   self.ingredient_lines << IngredientLine.where(attributes).first_or_initialize
end


Answer 2:

我遇到了类似的情况,找到了灵感在这个答案 。 总之,我不担心嵌套模式的重复,直到节省时间。

翻译成你的榜样,我加autosave_associated_records_for_ingredient_linesRecipe 。 它通过迭代ingredient_lines和执行find_or_create为你的直觉说。 如果ingredient_lines是复杂的,尤里的first_or_initialize方法可能是更清洁。

我相信这有你要找的行为:嵌套模型永远不会重复,但编辑一个导致了新的记录,而不是更新共享的一个。 有孤立的极大可能性ingredient_lines但是,如果这是一个严重的问题,你可以选择更新如果模型只有一个recipe与匹配当前的一个ID。



Answer 3:

老问题,但我有同样的问题。 忘了补充:ID白名单与轨道4个strong_parameters。

例如:

widgets_controller.rb

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

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 nested form on many-to-many: how to prevent duplicates?