关系数据库实现

时间:2013-04-25 00:21:16

标签: ruby-on-rails database model-view-controller database-design

不确定这是最好的实现方式。我有两种不同类型的属性,我想跟踪故障。我希望能够在特定属性的显示页面上显示故障,然后查看故障索引页面上的所有故障。

有多个与每个属性相关的故障表或每个属性链接到的故障表会更好吗?我担心在故障表中有多个空白id属性,如果它们全部放在一起的话。但如果它们分开了,我担心在视图中显示它们。我用rails实现这个。

一个故障表

Cars                   Trucks                Faults
-----------            ----------           -----------
car_id                 truck_id              fault_id
attribute_1            attribute_1           car_id
                                             truck_id
                                             fault description

两个故障表(每个属性一个)

Cars                   Trucks                car_Faults              truck_faults
-----------            ----------           -----------              -----------------
car_id                 truck_id              car_fault_id            truck_fault_id
attribute_1            attribute_1           car_id                  truck_id  
                                             fault description       fault description

2 个答案:

答案 0 :(得分:2)

您可以使用现有模型的多态关联,或单表继承将汽车和卡车组合成一个类。


多态关联如下所示:

Cars                   Trucks                Faults
-----------            ----------           -----------
id                     id                    id
attribute_1            attribute_1           faultable_id
                                             faultable_type
                                             fault description

您必须将faultable_id(int)和faultible_type(字符串)列添加到Fault。模型看起来像这样:

def Car < ActiveRecord::Base
  has_many :faults, :as => :faultable
end

def Truck < ActiveRecord::Base
  has_many :faults, :as => :faultable
end

def Fault < ActiveRecord::Base
  belongs_to :faultable, :polymorphic => true
end

允许您这样做:

@car.fault
# => returns car's fault

@fault.faultible
# => returns car or truck

单表继承(STI)如下所示:

Vehicle                Faults
-----------            ---------- 
id                     id   
type                   vehicle_id
attribute_1            fault description

理解这一点有点棘手,但CarTruck都将继承Vehicle超类的错误。这样,您只需使用一个数据库表(单表继承),就可以将汽车和卡车与故障相关联。

汽车和卡车将作为车辆记录存储,并将共享共同的属性。这对于具有几乎相同属性的模型(例如“颜色”或“制作”)非常理想。请记住,未使用的属性(卡车对象中的汽车属性)将为零。如果您正在处理许多不可互换的属性(因此很多nils),那么最好使用多态关联。

型号:

def Vehicle < ActiveRecord::Base
  has_many :faults
end

def Car < Vehicle
end

def Truck < Vehicle
end

def Fault < ActiveRecord::Base
  belongs_to :vehicle
end

你可以这样做:

@truck.fault
# => returns truck's fault

@fault.vehicle
# => returns either a Car or Truck object, depending on the type

使用STI时有一些注意事项:

  • 您必须实例化一个子类(Car或Truck); 从不实例化超类(即Vehicle.new)。请勿触摸type的{​​{1}}属性。 Rails会自动处理它。

  • 没有集合类方法,因此像Vehicle(所有卡车的故障)之类的东西都不起作用。

答案 1 :(得分:0)

如果您希望能够同时显示所有故障并且能够显示每个属性的故障,我认为这样的解决方案可能就是您正在寻找的

Vehicles                Faults                      Types
-----------            -----------                 ---------
vehicle_id             fault_id                    vehicle_type
vehicle_type(FK)       vehicle_id(FK)                  
attribute_1            vehicle_type(FK)
                       fault_description

然后在Types中有一个条目,一个用于Car,一个用于Truck

编辑:经过深思,我意识到vehicle_type中的Faults是不必要的,因为你可以使用Car个错误:

SELECT fault_id AS F FROM Faults WHERE F.vehicle_id IN
  SELECT vehicle_id FROM Vehicles AS V WHERE V.vehicle_type IN
    SELECT vehicle_type FROM Types WHERE vehicle_type = 'Car'