我有一个Recipe
模型,一个Ingredient
模型。现在是食谱
has_and_belongs_to_many :ingredients
和成分has_and_belongs_to_many
:recipes
。
因为可以想象一种成分可以由其他成分组成,所以我正在尝试在该模型上进行自联接,如下所示:
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>
显然,我需要一个关联表来存储成分/子成分的关系,但据我所知,这差不多。我尝试了各种壮举source
和through
魔法,但没有运气。
我还搞砸了一个多态关联,其中所有东西都有一个父对象,它要么是成分类型,要么是配方类型,但无法通过我想要的界面来解决。