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