我有一个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
巫术的壮举,没有运气。
我还搞乱了多态关联,其中一切都有 父母和它的类型成分或食谱类型,但无法得到 用我想要的界面来解决这个问题。
答案 0 :(得分:0)
想想我弄清楚了。使用this post的修改版本结束。
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
对亲子/后代命名非常满意。