Rails:检查现有记录(并使用现有记录)后创建实例和关联

时间:2018-10-07 04:24:05

标签: ruby-on-rails activerecord

我有一个非常具体的问题,似乎无法找到解决方案。如果这太具体了,请原谅我,但我不知道还有什么要问的。

我正在尝试通过关联创建具有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

我知道上面的代码完全是胡说八道,但是希望我的想法能够实现。我想使用现有记录(如果已经存在),否则创建一个新记录。

不过,我无法为实现这一目标而烦恼。任何帮助将非常感激!

1 个答案:

答案 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