【问题标题】:Table and Ruby ActiveRecord Class design for (sub)categories(子)类别的表和 Ruby ActiveRecord 类设计
【发布时间】:2011-08-25 22:41:05
【问题描述】:

我想我有一个相当简单的问题,因为我是 Ruby 新手,甚至是 ActiveRecords 新手。

我想要实现的是使用 ActiveRecords(和相应的 SQL 模式)的类表示,它对以下问题进行建模:

  • 存在类别和子类别(由 parent_id 建模)
  • 产品只属于一个类别
  • 每个产品可以有 0..inf 特征
  • 特征只是有一些数据字段,只被产品引用

我当前的架构如下图所示:

此架构是否适合 ActiveRecords?课程会是什么样子?我只是想不通 JoinTable 如何适合 ActiveRecord 结构。

此外,我如何对来自parent_id->categories.id 的链接进行建模?

任何帮助表示赞赏!

干杯

【问题讨论】:

    标签: sql ruby-on-rails ruby database activerecord


    【解决方案1】:

    要对您描述的关系进行建模,您会这样做:

    models/category.rb
    class Category < ActiveRecord::Base
        has_many :products
        has_many :subcategories, :class_name => "Category", :foreign_key => :parent_id
    end
    
    models/product.rb
    class Product < ActiveRecord::Base
        belongs_to :product
        has_many :features, :through => :product_features
        has_many :product_features
    end
    
    models/feature.rb
    class Feature < ActiveRecord::Base
      has_many :product_features
      has_many :products, :through => :product_features
    end
    
    models/productfeature.rb
    class ProductFeature < ActiveRecord::Base
      belongs_to :product
      belongs_to :feature
    end
    

    鉴于此结构,您可以将连接建模为多对多关系。这很有用,因为在 Rails 3.1 中,HABTM 样式的连接正在消失

    为了获取信息,我经常使用控制台 rails 控制台 进行测试,这样你就可以做

    @category = Category.first   #get the first category
    @category.subcategories      #returns an array of categories
    

    链接的遍历是通过您在模型中设置的关系,目的是在使用合理名称的情况下使其可读。根据您的问题,自联接也包含在Rails Guides: Associations 中,并提供了一个很好的示例。本指南的其余部分还详细介绍了其他关系。

    要记住的另一件事是创建迁移,以便使用作为外键的 id 创建连接表。

    【讨论】:

    • 由于最完整的答案,我选择你的作为最佳答案。它让我走上了正确的轨道,我想我现在掌握了它。类别仍然缺少belongs_to :parant_category, :class_name =&gt; "Category" 以允许上下遍历。但除此之外,一切似乎都是正确的。再次感谢!
    【解决方案2】:

    我的模型看起来像这样:

    class Category < ActiveRecord::Base
      has_many :products
    end
    
    class Product < ActiveRecord::Base
      belongs_to :category
      has_many   :product_features
      has_many   :features, :through => :product_features
    end
    
    class ProductFeature  < ActiveRecord::Base
      belongs_to :product
      belongs_to :feature
    end
    
    class Feature < ActiveRecord::Base
      has_many   :product_features
      has_many   :products, :through => :product_features
    end
    

    Rails 有一个名为has_and_belongs_to_many 的关联。 Rails 需要一个包含两列的表来存储连接数据。我通常使用双 has_many 来获得相同的结果,因为它使您可以灵活地在连接表中添加其他信息。

    示例代码

    product.category
    product.category = category1
    
    
    category.products
    category.products << product1
    
    
    product.features
    product.features << feature1
    
    feature.products
    feature.products << product1
    

    【讨论】:

    • 感谢您提供的广泛信息。这正是我一直在寻找的。当我彻底阅读您和格兰特的出色答案后,我很快就会接受答案。
    【解决方案3】:

    这是ActiveRecord::Associations::ClassMethods的API

    其中有很多不同关系以及如何构建它们的示例。值得花时间了解您如何/为何构建这些关联。

    对于多对多连接,您需要查看

    • has_many ..., :through =&gt; ...
    • has_and_belongs_to_many ...

    文档解释了何时以及为什么要使用它们。

    【讨论】:

    • 谢谢,现在您的答案包含实际信息 :-) 就我现在所见,这意味着我根本不需要为连接表建模。但是映射器如何知道我的连接表的名称?我可以以某种方式指定它吗?
    • 如果您阅读 API 文档,就会发现很多名称推断正在进行(记住 rails 是 convention over configuration)。这就是为什么当你开始做这种工作时会绊倒你的原因——我最近一直在为多对多连接的自我参照而苦苦挣扎
    猜你喜欢
    • 2021-12-12
    • 2020-08-04
    • 2015-10-15
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    • 2011-07-20
    • 1970-01-01
    相关资源
    最近更新 更多