2012-04-15 57 views
1

我有一個車型的型號:Rails的:如何在車輛及其所有類型

class Vehicle < ActiveRecord::Base 
validates_presence_of :num_of_wheels 
validates_presence_of :make 
validates_presence_of :model 
end 

從這節課,我想有車輛類型的可擴展的數字,如「乘用車」 ,「摩托車」,「卡車」,每個都有自己獨特的強制性屬性。例如,PassengerCar可能需要門的數量,但不適用於摩托車類型。與此同時,摩托車和passenger_cars在創建時應該要求/繼承Vehicle的強制性屬性。

這裏的關鍵是我不能真正預測可能發明或需要存儲的不同類型車輛的數量。所以,我需要一種可擴展的方式來添加新的車輛類型。此外,就用戶界面和視圖而言,如果我的類型不能從下拉菜單中獲得,並且使用db填充Vehicle類型,並且可以創建新的Vehicle類型有反射回用戶界面。

用Rails建立這種關係的最佳方式是什麼?我正在考慮使用has_one:through關係,但我不確定這是最好的方法。例如,車輛將被分配給運營商。而且一個人可以在同一時間運行只有一輛車......所以,我可以說:

class Vehicle < ActiveRecord::Base 
has_one :motorcycle, :through => :vehicle_type 
has_one :passenger_car, :through => :vehicle_type 
has_many :vehicle_types 
validates_presence_of :num_of_wheels 
validates_presence_of :make 
validates_presence_of :model 
end 

class VehicleType < ActiveRecord::Base 
belongs_to :vehicle 
belongs_to :passenger_car 
belongs_to :motorcycle 
end 

class PassengerCar < ActiveRecord::Base 
belongs_to :vehicle_type 
validates_presence_of :doors 
end 

class Motorcycle < ActiveRecord::Base 
belongs_to :vehicle_type 
validates_presence_of :saddlebags 
end 

但是,似乎笨拙不得不每一個可能的類型添加到車輛的車型,並且由於運營商不僅可以每次駕駛一輛汽車時,將所有其他類型的汽車放置在Vehicle模型的has_one語句中似乎是多餘的。

任何想法非常感謝!

+0

你可能想考慮閱讀單表繼承機制。這裏有一篇很好的文章描述它:http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html – rjz 2012-04-16 00:55:13

回答

0

一個選項是設置這種關係了使用Rails的single table inheritance mechanism,要麼附加表的列(快)或序列化的哈希爲每個細節(如果要添加新的屬性將不需要新的遷移)模型。這裏的想法:

添加type列到是創造你的vehicles表給小費的Rails關你想使用單表繼承遷移:

def change 
    create_table :vehicles do |t| 
    t.string :type 

    # if using serialization 
    t.text :parameters 

    # if using custom fields 
    t.integer :saddlebags 
    t.integer :doors 

    # ... 
    end 
end 

您將使用的車輛爲基礎類,並從這裏開始了您的具體車輛將繼承它的基本屬性:

class Vehicle < ActiveRecord::Base 
    validates_presence_of :num_of_wheels, :make, :model 

    # if using serialization 
    serialize :parameters, Hash 

    # ... 
end 

class PassengerCar < Vehicle 
end 

class Motorcycle < Vehicle 
end 

# etc.. 

現在,當Operator被分配到車輛,Rails會自動地恢復相應的類別:

# models/Operator.rb 
class Operator < ActiveRecord::Base 
    has_one :vehicle 
end 

# in controller action 
op = Operator.new 
op.vehicle = Motorcycle.new 
op.vehicle.save 
op.save 
# op will now be assigned to a +Motorcycle+ the next time it's loaded 

如果您在表中使用其他列,驗證將按照您的描述進行操作。但是,如果您選擇將它們序列化爲parameters,則最好的辦法可能是爲每個型號的parameters散列生成custom validators

+0

這是完美的!感謝您的完整想法!由於我不希望有太多獨特的屬性,我認爲只需添加單獨的表格列就足夠了。另外,當我在數據庫中序列化數據時,我有點畏縮。 – Sly 2012-04-16 17:16:10

相關問題