【问题标题】:Setting up DB tables in Rails在 Rails 中设置数据库表
【发布时间】:2014-04-28 07:00:29
【问题描述】:

我正在尝试使用 Ruby/Rails 设置以下基础架构。在这里解释我的问题是我试图设置的表的类比: 假设我有 3 个主要项目要建模/表示为表格:零件、制造商和汽车。因此,零件表包含所有由制造商制造的独特组件。制造商表包含制造零件的所有独特制造商。汽车表包含所有独特的汽车。汽车由零件组成,制造商制造许多零件。我可以用来表示这些信息的最有效的表结构是什么?我希望能够查询给定汽车品牌中的所有零件是什么以及谁制造了零件。我是 DBs 的新手,Rails 的新手,所以想了解我在顺利实现这一目标方面的选择。

【问题讨论】:

    标签: sql ruby-on-rails database schema


    【解决方案1】:

    Partbelong_to :manufacturerhas_many :cars

    Carhas_many :parts

    Manufacturer' 'has_many :parts

    阅读this 了解如何设置的详细说明。

    【讨论】:

      【解决方案2】:

      如果我正确理解您的问题:

      1. 一家制造商生产多种不同类型的零件,但每种类型的零件仅由一家制造商制造。

      2. 一辆汽车包含多种类型的零件,一种类型的零件可以用于多种类型的汽车。

      3. 对于给定类型的汽车,您想知道哪个制造商为该汽车制造了零件。

      在这种情况下,您可以在制造商、零件和汽车模型之间建立以下关联:

      1. 制造商和零件之间的“一对多”(1:M) 关联。 (将has_many :parts 添加到manufacturer.rb 并将belongs_to :manufacturer 添加到part.rb。)

      2. 零件和汽车之间的“多对多”(M:M) 关联。 (将has_and_belongs_to_many :cars 添加到part.rb 并将has_and_belongs_to_many :parts 添加到car.rb。)

      3. 一个“has_many :through”协会,从汽车到零部件再到制造商。 (将has_many :manufacturers, through: :parts 添加到car.rb。)

      然后,使用迁移为每个模型创建一个表。

      对于制造商和零件之间的 1:M 关联,​​零件表中应该有一个名为 manufacturer_id 的列。每个部件的manufacturer_id(或“外键”)是一个整数,等于制造商表中特定制造商的id(或“主键”)。换句话说,该零件“属于”该制造商。许多其他部件也可以属于该制造商。

      对于零件和汽车之间的 M:M 关联,​​您需要创建一个附加表 (with a model),其中包含名为 parts_idcars_id 的列。这称为“连接表”。如果零件 X 包含在汽车 Y 中,则连接表将有一行,其中parts_id 等于 X,cars_id 等于 Y。这样,一个零件可以有很多辆汽车,反之亦然。

      汽车和制造商之间的关联是间接的。一辆车可以有很多零件,每个零件都属于一个制造商。因此,一辆汽车可以有多个制造商。

      Here's the best introduction to relational databases that I've found.

      还有一件事:对于 M:M 关联,​​您可以使用双面 has_many :through,而不是双面 has_and_belongs_to_many。无论哪种方式,关联都需要三个表(parts、cars 和将它们连接在一起的表)。我不会在 HMT 和 HABTM 之间的 debate 中进入 explaining 的所有 differencestaking a side。我认为底线是,“has_and_belongs_to_many”更简单,但“has_many :through”会给你的应用更多的灵活性,尤其是在以后。

      --根据评论进行编辑--

      每个表都自动包含一个名为id 的整数列。这就是primary key。所以不需要在零件表中添加part_id,在制造商表中添加manufacturer_id等。

      但由于制造商和零件之间存在1:M association,零件表将需要一个外键manufacturer_id。如果零件属于制造商,则零件表中该零件行的外键必须等于制造商表中该制造商行的主键。

      请注意,许多外键可以指向同一个主键,反之则不行。

      M:M associations 有点不同。汽车表和零件表都不需要外键。相反,必须有第三个表,其中包含名为car_idpart_id 的外键列。

      部件表不需要manufacturer_name 列。制造商名称将位于制造商表中名为 name 的列中。您可以通过遵循零件与其制造商之间的关联来获得它。例如,如果@my_part 是表示某个部件的 Ruby 对象,那么@my_part.manufacturer 将提供该部件的制造商,@my_part.manufacturer.name 将提供该部件的制造商名称。

      显示信息本身就是另一个话题!可以这么说,您可以创建一个对象来表示一辆 id 为 X 的汽车的所有部件,如下所示:@parts_for_this_car = Part.where(car_id: X)

      然后,@parts_for_this_car 对象将是一个数组(具体来说,是一个 Part 对象数组)。在一个控制器动作中创建这个对象(比如controllers/car_controller.rb中的def show),你可以在对应的视图文件(比如views/cars/show.html.erb)中使用它。

      【讨论】:

      • 嗨,第 1 点和第 2 点是正确的,但对于第 3 点:对于给定的汽车,我希望能够列出它所组成的所有部件。在零件架构中,我将拥有零件 ID、零件名称、制造商 ID、制造商名称和更多字段。在制造商模式中,我将拥有制造商 ID、制造商名称和其他一些其他字段。在 Car 模式中,我想拥有 car_name 和 car_id 以及其他一些其他字段。我可以以某种方式进行设置,以便当我转到汽车的显示 URL 时,它可以自动显示汽车的所有部件吗?我想我需要零件表中的 car_id?
      • 好的,我编辑了我的答案以考虑您的评论。它现在回答你的问题了吗?如果有,请将其标记为答案。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-28
      • 2011-10-05
      • 1970-01-01
      相关资源
      最近更新 更多