【问题标题】:Rails: Modeling a list that can contain both items and listsRails:建模一个可以同时包含项目和列表的列表
【发布时间】:2014-08-21 05:08:30
【问题描述】:

我无法在 Rails 中为特定类型的列表建模。

基本上,我想建模一个列表,其成员包含其他列表或单个项目。

假设我有一张汽车零件表

Table Part
name
cost
color

假设某些部件列表非常常见,所以我想定义一些部件列表并重用这些列表。例如:

Table PartList
name

Table PartListItem
part_id
partList_id
position

现在,如果我想显示特定汽车所需的物品,我想要一个列表,其成员可能是特定汽车的特定物品,并且成员是可以在许多汽车中找到的常见捆绑物品列表.

可能看起来像这样:

普通汽车的零件清单:
- 发动机零件清单
- 身体零件清单
- 前保险杠
- 后保险杠
- 尾管
- 安全合规零件清单

高档汽车零件清单:
- 发动机零件清单
- 身体零件清单
- 闪亮的前保险杠
- 闪亮的后保险杠
- Wizbang 尾管
- 安全合规零件清单

如果我要修改“引擎”的零件列表,查看任一汽车零件列表都会反映更改。无论列表的层次结构如何,列表都可能包含更多列表或单个项目。

一旦所有列表都“展开”,它们的内容都是“部分”

我可能错了,但这不完全是递归,不完全是树,也不完全是嵌套集合。感觉有点像菜单系统,但“菜单”的每个成员可能有很多属性。

这类问题是否有 DRY 解决方案?我很乐意接受一些,呃...缺乏干燥度,如果它有助于我能理解的解决方案。

【问题讨论】:

标签: sql ruby-on-rails model nested hierarchy


【解决方案1】:

在我看来STIHABTM 可以解决您的问题。

您想设计如下内容:

Car 可以有多个部分,Part 可以是单个 PartItemPartList。而一个PartList 可以有多个PartItem

在 Rails 中会是这样的:

# migrations
class CreateCars < ActiveRecord::Migration
  def change
    create_table :cars do |t|
      t.string :model
    end
  end
end

class CreateParts < ActiveRecord::Migration
  def change
    create_table :parts do |t|
      t.string :type # STI
      t.string :name
    end
  end
end

class CreateCarsParts < ActiveRecord::Migration
  def change
    create_table :cars_parts do |t|
      t.integer :car_id
      t.integer :part_id
    end
  end
end

class CreatePartListsPartItems < ActiveRecord::Migration
  def change
    create_table :part_lists_part_items do |t|
      t.integer :part_list_id
      t.integer :part_item_id
    end
  end
end

# models
class Car < ActiveRecord::Base
  has_and_belongs_to_many :parts
end

class Part < ActiveRecord::Base
  has_and_belongs_to_many :cars
end

class PartItem < Part
  has_and_belongs_to_many :part_lists,
                          join_table: :part_lists_part_items
end

class PartList < Part
  has_and_belongs_to_many :part_items,
                          join_table: :part_lists_part_items
end

希望对您有所帮助。

【讨论】:

  • 太好了。应该管用。不过,我想吹毛求疵。 “Part”可以是单个 PartItem 或 PartList”的断言在建模方面是准确的,但在语言上是无意义的。我想就为我的问题找到解决方案而言应该没关系。我被绊倒了-在语言学变得毫无意义之前,我会一直走下去。当我不能用简单的句子来描述关系时,这对我来说是一个警钟。我会不断提醒自己,“部分”可以是一个项目,也可以是一个项目列表,但我希望它有另一个名字。无论如何,感谢您的出色回答。
  • 我不同意“语言上的废话”,您会订购发动机,而不是曲轴、活塞、油底壳等……许多汽车零件只是其他零件的集合。
  • 我不是语言专家,所以我可能会在这里偏离基础。令我震惊的是,“零件”是有形的物品。说“零件”与“零件列表”是一回事,这有点牵强
  • 自从了解了 STI,我想我可以这样说。命名使用 STI 的表对我来说可能是一个挑战。 STI 表表示(包含)多个相似但不同的类。几乎按照定义,使用单个名称引用这样的表必须在精度上有所妥协。
  • 或者另一种可能更好的说法:“现实世界中没有一个单词超类可以同时描述 PartLists 和 PartItems。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多