我有一个非常具体的问题,似乎无法找到解决方案。如果这太具体了,请原谅我,但我不知道还有什么要问的。
我正在尝试通过关联创建具有has_many的模型的实例,但是has_many关联是“主”记录类型表的一部分,其中仅存在1条记录(与联接表一起联接)
我正在尝试实现以下目标:
使用带有成分的accepts_nested_attributes_for创建食谱。仅当在成分表中找不到该成分时,才可以使用该成分。但是,如果找到了,我要使用已经存在的记录。
如果我们需要特定的示例,请按以下步骤操作:
假设我们正在创建一个食谱“辣椒”,其中包括豆类,洋葱和牛肉末。豆类和洋葱是全新的配料(在配料表中未找到),但碎牛肉已经存在于表中。我不想创建另一个碎牛肉记录,而是要使用成分表中已经存在的碎牛肉记录。
我该怎么做?
我认为也许我可以在Recipe模型上使用before save: :check_if_exists
调用,并通过check_if_exists
检查表单的所有成分是否存在。相关代码:
食谱模型
before_save :check_if_exists
def check_if_exists
self.ingredients.each do |ingredient|
if Ingredient.exists?(ingredient.name)
return ingredient
else
@ingredient = Ingredient.new(name: ingredient.name)
return @ingredient
end
end
end
我知道上面的代码完全是胡说八道,但是希望我的想法能够实现。我想使用现有记录(如果已经存在),否则创建一个新记录。
不过,我无法为实现这一目标而烦恼。任何帮助将非常感激!
答案 0 :(得分:0)
文档(https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html)说得很清楚,您可以将id
添加到关联记录的哈希中,而无需创建新的成分,而将使用旧的成分。
因此,我认为在您的用于过滤参数以节省参数的消毒方法中,您可以添加一些验证成分是否存在。像这样:
params.require(:recipe).permit(:name, ingredients_attributes: [:name]).tap do |p|
p[:ingredients_attributes].each do |i|
ingredient = Ingredient.find_by(name: i[:name])
i[:id] = ingredient.id if ingredient
end
end