【问题标题】:Polymorphic association to either another model or parent model与另一个模型或父模型的多态关联
【发布时间】:2012-06-09 14:46:22
【问题描述】:

我在 Rails 中有一个名为 Recipe 的模型。配方模型包含成分。每个成分行都与食物模型或另一个食谱相关联。所以基本上我想要一个与 Food 模型和 Recipe 模型的多态关联。但是,当我进行更改时,成分类中的 recipe_id 始终为空。关联中有什么明显的错误吗?

class Recipe < ActiveRecord::Base
  has_many :ingredients, :as => :element
end

class Food < ActiveRecord::Base
  has_many :ingredients, :as => :element
  has_many :recipes, :through => :ingredients
end

class Ingredient < ActiveRecord::Base
  belongs_to :element, :polymorphic => true
  belongs_to :recipe
end

因此,基本上一个食谱的成分行可以包含另一个食谱或食物表中的一个元素(并且每个食谱可以包含任意数量的成分行)。

这是一张代表我想要的图:

以下是 RubyMine 中当前模式的外观:

问题是成分行(即父表)中的 recipe_id 现在为空,所以当我开始实现多态关联时,关系已经停止工作。

以下是我保存食谱时的插入行:

  SQL (3.4ms)  INSERT INTO "recipes" ("created_at", "description", "directions", "name", "owner", "recipe_source_type_id", "servings", "source", "time", "updated_at", "visibility") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id"  [["created_at", Sun, 10 Jun 2012 13:43:12 UTC +00:00], ["description", "Þetta er önnur prufuuppskrift"], ["directions", "Já, og leiðbeiningar"], ["name", "Prufuuppskrift II"], ["owner", 1], ["recipe_source_type_id", 1], ["servings", 3], ["source", "aaa"], ["time", 3], ["updated_at", Sun, 10 Jun 2012 13:43:12 UTC +00:00], ["visibility", 0]]
  SQL (0.9ms)  INSERT INTO "ingredients" ("created_at", "description", "element_id", "element_type", "order", "qty", "recipe_id", "unit_type_id", "updated_at", "user_entered_qty") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id"  [["created_at", Sun, 10 Jun 2012 13:43:13 UTC +00:00], ["description", "abc"], ["element_id", 9], ["element_type", "Recipe"], ["order", nil], ["qty", 2.0], ["recipe_id", nil], ["unit_type_id", 1], ["updated_at", Sun, 10 Jun 2012 13:43:13 UTC +00:00], ["user_entered_qty", "2 gramm"]]

我之后要解决的另一个问题是 element_type 在这种情况下应该是 Food 而不是 recipe。我不确定在哪里设置。

【问题讨论】:

  • 嗯......我想没有人对此有任何解决方案:-(

标签: database ruby-on-rails-3 activerecord polymorphism models


【解决方案1】:

据我了解,一种成分可以同时属于食物和食谱。如果是这种情况,那么您的多态关联 Element 将负责处理。

它将在您的成分表中创建 2 个字段,一个名为 element_typeelement_id,其中 element_type 将包含与哪个表相关,element_id 将包含表中记录的 ID element_type 所指的那个。

这会使您的belongs_to :recipe 变得多余。事实上,当您将成分分配给配方时,Rails 会为您填充“多态字段”,而不是填充 recipe_id,因为您已经告诉它通过设置 :polymorphic =&gt; true 来填充多态字段。

我希望这可以解释您的困境。记住我告诉过你的内容,看看这个RailsCast on Polymorphic Associations,事情应该会解决的。

希望我能帮上忙。

【讨论】:

  • 清除。一个食谱有 x 种成分。每条配料线都连接到一些食物(如苹果、牛奶等)或另一个食谱(如披萨面团,它本身就是一个食谱,可以通过配料成为另一个食谱(一些披萨)的一部分)。所以我认为你说的不太正确。
  • 请记住,您永远不应该循环关系。这可能是一场“合乎逻辑的”噩梦,你可能最终会陷入无限循环(即,你不应该有一个属于一个配方的配料,该配方有一个配料,属于一个配料......你明白了)。目前,您的成分通过多态性同时属于您的食谱和食物,并通过正常关联再次属于食谱。这就是为什么它被设置为 nil (你在问题中提到你的错误是什么)。
  • 现在要解决您的问题,为什么不在Recipe 中创建另一个关系,例如belongs_to :recipe, as: :complex_recipes, through: :complex,其中complex 是一个包含2 个ID 字段的连接表,都链接到Recipe 模型。这样你就会有一个多对多的,比如一个食谱有很多食谱。这将允许您的成分属于您的模型,并且您的配方属于另一个配方,而不会在您的关联中创建循环。欢迎再次与我联系。
  • 成分表保留为多态表,这样您就可以拥有属于食物和食谱的成分。当您创建“复杂”表(或更好的名称哈哈)时,使用 recipe_id 和包含_recipe_id 创建它。这将允许您拥有一个属于多个食谱的食谱。在任何情况下,您都应该删除成分表中的belongs_to :recipe,因为它已经被多态关联处理了(这就是为什么它总是为零)
  • 是的,但您的解释不是 100%。您正在更改它,以便每个配方行可以有许多配方行(通过复杂表),并且一个配方可以有许多成分。因此,一个菜谱可以有很多菜谱,每个菜谱可以有很多成分(或相关的菜谱)。并且不要忘记每个食谱可以有很多食物。
猜你喜欢
  • 1970-01-01
  • 2011-05-06
  • 2011-01-30
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多