【问题标题】:How do I set up a has_many, polymorphic, self-referential relationship如何建立 has_many、多态、自引用关系
【发布时间】:2021-09-20 16:21:13
【问题描述】:

我正在尝试建立这样的关系:

我正在列出多本食谱书中的所有食谱。一个食谱只能属于一本食谱书。配方有一个成分列表,可以是单独的成分或其他配方。

例如,我有一份沙拉的食谱,其中包括生菜(一种成分)、西红柿(一种成分)和调味品(一种食谱)。然后,调料会列出它自己的成分。

我想在 Recipe 类上使用称为“组件”的多态关系,它将自引用 Recipe 类或引用成分类。

对于一个食谱,我还希望能够查看它是否用于任何其他食谱以及总成分是什么(即它是直接成分及其组成食谱的所有成分)

谁能告诉我如何设置?我知道如何做其中之一,但不是两者兼而有之。

谢谢!

【问题讨论】:

    标签: ruby-on-rails polymorphic-associations self-referencing-table


    【解决方案1】:
    class Recipe < ApplicationRecord
      has_many :recipe_components
      has_many :components, through: :recipe_components
    end
    
    rails g model recipe:belongs_to component:belongs_to{polymorphic}
    class RecipeComponent < ApplicationRecord
      belongs_to :recipe
      belongs_to :component, polymorphic: true
    end
    

    这将使您可以将食谱与配料、其他食谱或您喜欢的任何其他类别相关联。然而,当您将外键放在指向同一个表的表上时,它并不是真正的自引用关联。

    这两个概念实际上是互斥的*,因为定义的自连接总是指向一个固定的表(本身)。碰巧两次引用同一个表的连接表不是自引用的。

    # Not self-referential 
    class Friendship < ApplicationRecord
      belongs_to :user, class_name: 'User'
      belongs_to :other_user, class_name: 'User'
    end
    

    对于一个食谱,我还希望能够查看它是否用于任何其他食谱

    一旦你想在树上走另一条路,事情就会开始变得疯狂:

    class Recipe < ApplicationRecord
      has_many :recipe_components_as_component,
        class_name: 'RecipeComponent',
        as: :component
      has_many :recipies, through: :recipe_components_as_component 
    end
    

    以及总成分是什么(即直接成分及其成分配方的所有成分)

    这需要您使用递归“遍历树”并获取每个级别的所有关联项。一个巨大的问题本身,很可能会导致你后悔使用多态性。有several gems that tackle this problem

    【讨论】:

    • * 或者至少应该是。严格来说,多态关联实际上并没有引用任何东西,因为将面向对象的代码与关系数据库混合在一起是一种不可靠的黑客攻击。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多