我在 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

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

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

例如,假设对于 recipe_1,一个具有 {"measurement_unit_id"=> 1, "ingredient_id"=> 1, "quantity"=> 3.5} 的 IngredientLine 是相关联的,如果对于 recipe_5,IngredientLine 子表单由用户使用相同的值编译,我不想在 IngredientLine 表上有新记录,而只想在连接表成分线_recipes 上有新的关联记录。

请注意,目前我没有任何 IngredientLine Controller ,因为保存和更新 IngredientLines 是由嵌套表单例程处理的。甚至我的 Recipe Controller 也是简单而标准的:
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 表中,rails 当然不应该在 IngredientLine 表上写任何东西,但也应该区分已经关联到父记录的子记录,以及需要为其创建关系的新子记录,在连接表上写入新记录。

谢谢!

最佳答案

在配方模型中重新定义方法

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

关于ruby - 多对多 : how to prevent duplicates? 上的 Rails 嵌套形式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10717797/

10-13 04:44