如果我正确理解您的问题:
一家制造商生产多种不同类型的零件,但每种类型的零件仅由一家制造商制造。
一辆汽车包含多种类型的零件,一种类型的零件可以用于多种类型的汽车。
对于给定类型的汽车,您想知道哪个制造商为该汽车制造了零件。
在这种情况下,您可以在制造商、零件和汽车模型之间建立以下关联:
制造商和零件之间的“一对多”(1:M) 关联。 (将has_many :parts 添加到manufacturer.rb 并将belongs_to :manufacturer 添加到part.rb。)
零件和汽车之间的“多对多”(M:M) 关联。 (将has_and_belongs_to_many :cars 添加到part.rb 并将has_and_belongs_to_many :parts 添加到car.rb。)
一个“has_many :through”协会,从汽车到零部件再到制造商。 (将has_many :manufacturers, through: :parts 添加到car.rb。)
然后,使用迁移为每个模型创建一个表。
对于制造商和零件之间的 1:M 关联,零件表中应该有一个名为 manufacturer_id 的列。每个部件的manufacturer_id(或“外键”)是一个整数,等于制造商表中特定制造商的id(或“主键”)。换句话说,该零件“属于”该制造商。许多其他部件也可以属于该制造商。
对于零件和汽车之间的 M:M 关联,您需要创建一个附加表 (with a model),其中包含名为 parts_id 和 cars_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 的所有 differences 或 taking 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_id 和part_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)中使用它。