rails:如何动态创建记录并用ID替换值?

时间:2017-02-14 23:55:13

标签: ruby-on-rails ruby-on-rails-5

我有3个型号:

用餐

has_many :ingredients

has_and_belongs_to_many :products

产品:

has_and_belongs_to_many :meals

成分:

belongs_to :product

belongs_to :meal

用于膳食中的成分我使用accepts_nested_attributes_for :ingredients

我想使用模型Product存储产品名称,在模型Ingredients中我想使用product_id(我不想重复产品名称,并且会使用产品对于股票,这就是为什么它们必须是独一无二的。)

挑战又名问题

我正在创建用户定义膳食名称和成分的表单 - 保存表单后,我想动态创建产品(如果它不存在和/或使用Ingredients中的product_id并添加product_idmeal_id到联接表(has_and_belongs_to_many - 餐饮 - 产品)

所以@meal.save不会做魔术,我怎么能这样做呢?我应该将节约的食物除以产品和配料的整体逻辑,还是铁路有可能做到这一点?

以下是表格:

enter image description here

保存表单后我得到的结果(product_name是成分的访问者)

    "meal"=>
  {"name"=>"Mango Chicken",
   "ingredients_attributes"=>
    {"0"=>{"product_name"=>"Rice", "quantity"=>"50", "qty_type"=>"gr"},
     "1"=>{"product_name"=>"Chicken", "quantity"=>"120", "qty_type"=>"gr"},
     "2"=>{"product_name"=>"Mango", "quantity"=>"1", "qty_type"=>"pcs"},
     "3"=>{"product_name"=>"Chili", "quantity"=>"2", "qty_type"=>"pcs"},
     }},

1 个答案:

答案 0 :(得分:2)

您可以在Ingredient模型的before_save回调中执行此操作。如果产品不存在,回调将创建产品,并更新产品/餐饮连接表。

如果product_name不是ingredients表中的列,则需要在attr_accessor中定义它。

class Ingredient < ActiveRecord::Base

  attr_accessor :product_name

  before_save :update_products

  def update_products

    return unless product_name.present? 
    self.product = Product.find_or_create_by(name: product_name) 
    meal.products << self.product unless meal.products.include?(self.product)
    meal.save
  end
end

但我强烈建议你摆脱HABTM联接表。它没有标准化,所以可以与成分“不同步”...当你删除一个成分时,你需要一种机制来删除HABTM条目。

更好的是......

class Meal < ActiveRecord::Base

  has_many :ingredients
  has_many :products, through: ingredients

和...

class Product < ActiveRecord::Base

  has_many :ingredients
  has_many :meals, through: ingredients