Ruby on rails 配料有许多子配料

Ruby on rails 配料有许多子配料,ruby-on-rails,database-design,Ruby On Rails,Database Design,我有一个配方模型和一个配料模型。现在有一个食谱 has_和属于许多:配料和配料has_和属于许多 :配方 因为一种成分可能是由其他成分组成的,所以我 尝试在该模型上进行自联接,如下所示: has_many :components, class_name: 'Ingredient', foreign_key: 'parent_id' belongs_to :parent, class_name: 'Ingredient' 现在,这是可行的,但每种成分只能有一个母体,例如蛋黄酱 是在“蟹肉蛋糕

我有一个
配方
模型和一个
配料
模型。现在有一个食谱
has_和属于许多:配料
和配料
has_和属于许多
:配方

因为一种成分可能是由其他成分组成的,所以我 尝试在该模型上进行自联接,如下所示:

has_many :components, class_name: 'Ingredient', foreign_key: 'parent_id'
belongs_to :parent,   class_name: 'Ingredient'
现在,这是可行的,但每种成分只能有一个母体,例如蛋黄酱 是在“蟹肉蛋糕”的成分中,这是食谱的一部分,但它不能 成为其他食谱中“辛辣蛋黄酱”的一种成分 同时

我想得到的是这样一个界面:

r = Recipe.create(name: "Jumbo Lump Crab Cakes")
r.ingredients << Ingredient.create(name: "Crab Cakes")
r.ingredients[0].ingredients # => []
r.ingredients[0].ingredients.create(name: "Mayonnaise")
r.ingredients[0].ingredients # => [#<Ingredient id: 2, name: "Mayonnaise">]
r.ingredients[0].ingredients[0].ingredients.create(name: "Eggs")
r.ingredients[0].ingredients[0].ingredients # => [#<Ingredient id: 3, name: "Eggs">]

Ingredient.last               # => #<Ingredient id: 3, name: "Eggs">
Ingredient.last.parent        # => #<Ingredient id: 2, name: "Mayonnaise">
Ingredient.last.parent.parent # => #<Ingredient id: 1, name: "Crab Cakes">

# Bonus points if a child ingredient can "walk up" its heritage tree to the recipe:
Ingredient.last.recipe        # => #<Recipe id: 1>
r=Recipe.create(名称:“巨型块蟹饼”)
r、 成分[]
r、 配料[0]。配料。创建(名称:“蛋黄酱”)
r、 配料[0]。配料#=>
r、 配料[0]。配料[0]。配料。创建(名称:“鸡蛋”)
r、 配料[0]。配料[0]。配料#=>
配料.最后一次#=>#
component.last.parent#=>#
component.last.parent.parent#=>#
#如果儿童配料可以“走上”其传统树进入配方,则可获得额外积分:
配料.last.recipe#=>#
显然,我需要一个关联表来存储成分/子成分 关系,但这是我所知道的。我试过各种各样的方法
源代码
通过
魔法的专长,没有运气

我还搞砸了一个多态关联,所有的东西都有一个 父母和它的类型成分或类型配方,但无法得到
这就是我想要的界面。

我想我已经解决了。最终使用的是修改版的

create_table:配料做:狩猎
t、 参考文献:父母#:捕食者
t、 参考文献:儿童:猎物
结束
添加索引:配料、父母id、狩猎、捕食者id
添加索引:配料、儿童id、狩猎、猎物id
创建|U表格:组件do | t |#:动物
t、 字符串:名称
结束
类组件

对父母/后代的命名相当满意。

而且你没有提到一个配方可以是另一个配方的成分,也可以是一个成分的子成分。我想你可以说,有子成分的成分只是制作该成分的“配方”,但这更像是一个语义问题。对我来说,食谱可以有子食谱是没有必要的。想想经典的材料清单吧——不要被术语挂住。例如,蛋黄酱本身可能由蛋黄、油、芥末、泡菜等制成。甚至像“鸡蛋”这样的基本“成分”也可以被视为由“蛋黄”和“白”构成。您所指的“配方”是
成分和
组装说明的关联,其本身可能是一个子组件,就像“飞机”是由“螺钉、螺栓和垫圈”和其他一些东西以特定方式组装而成一样。
create_table :ingredients do |t| # :hunts
  t.references :parent # :predator
  t.references :child  # :prey
end

add_index :ingredients, :parent_id # :hunts, :predator_id
add_index :ingredients, :child_id  # :hunts, :prey_id

create_table :components do |t| # :animals
  t.string :name
end

class Component < ActiveRecord::Base # Animal
  has_many :parentage, foreign_key: 'parent_id',
                       class_name: 'Ingredient',
                       dependent: :destroy

  has_many :children, through: :parentage

  has_many :progeny, foreign_key: 'child_id',
                     class_name: 'Ingredient',
                     dependent: :destroy

  has_many :parents, through: :progeny
end

class Ingredient < ActiveRecord::Base # Hunt
  belongs_to :parent, class_name: 'Component'
  belongs_to :child,  class_name: 'Component'
end