2016-04-02 55 views
0

有兩種車型:汽車(如奧迪,奔馳)和選件(ABS,激光頭燈,夜視...)。汽車habtm選項。多變模型的延伸

假設奧迪和梅賽德斯「夜視」選項均可用。 但在梅賽德斯奔馳時,您需要爲此選項支付額外的費用。所以正如我猜測,我需要延長我的選擇模式,以存儲選項的一些汽車的額外價格。我認爲汽車模型也應該修改。但無法想象如何。

我的目標實現的行爲是這樣的:

Audi.options.night_vision.extra_price =>零

Mercedes.options.night_vision.extra_price => 300

當然,我唐」不想在每輛車的選項集合中複製「夜視」選項。

謝謝。

+0

audi.options.night_vision.extra_price(奧迪),但不優雅的解決方案 – Roger

回答

0

這既不是最簡單的,也不是最優雅的,只是一個應該基於你如何實現選項的假設工作的想法。如果您需要更多幫助,請回到我身邊。

爲了實現audi.options.night_vision.extra_price我假設你有一個模型,如:

class car 
    include Mongoid::Document 
    field :name, type: String 
    has_and_belongs_to_many :options do 
    def night_vision 
     @target.find_by(name:'night_vision') 
    end 
    end 
end 

class option 
    include Mongoid::Document 
    field :name, type: String 
    field :extra_price, type: Float 
    has_and_belongs_to_many :cars 
end 

這將使你做:

audi = Car.find_by(name:'audi') 
audi.options.night_vision.extra_price 

如果上述假設是正確的,你應該可以像這樣修改你的班級:

class option 
    include Mongoid::Document 
    attr_accessor :extra_price 
    field :name, type: String 
    has_and_belongs_to_many :cars 
    embeds_many :extras 
end 

class extra 
    include Mongoid::Document 
    field :car_id, type: String 
    field :price, type: String 
    embedded_in :option 
end 

class car 
    include Mongoid::Document 
    field :name, type: String 
    has_and_belongs_to_many :options do 
    def night_vision 
     extra = @target.find_by(name:'night_vision') 
     extra_price = extra.prices.find_by(car_id: @target._id.to_s) if extra 
     extra.extra_price = extra_price.price if extra && extra_price 
     return extra 
    end 
    def find_or_create_option(args) 
     extra = @target.find_or_create_by(name:args) 
     price = extra.extras.find_or_create_by(car_id:@target._id.to_s) 
     price.set(price: args.price 
    end 
    end 
end 

這應該可以讓你來填充你的選項,如:

audi.options.find_or_create_option({name:'night_vision', price:2310.30}) 
bmw.options.find_or_create_option({name:'night_vision', price:1840.99}) 

audi.options.night_vision.extra_price 
=> 2310.30 
bmw.options.night_vision.extra_price 
=> 1840.99 

如果你試圖找到一個汽車night_vision不具有night_vision你會得到:

skoda.options.night_vision 
=> nil 
skoda.options.night_vision.extra_price 
=> NoMethodError (undefined method 'extra_price' for nil:NilClass) 
+0

我的解決方案: http://pastebin.com/ZgrJtEa3 – Roger

+0

很高興您想出了一個解決方案。我不建議這樣做,因爲您希望.night_vision的範圍,以便您可以做audi.options.night_vision.extra_price而不是audi.options.first.extra_price – ABrowne

+0

抱歉誤導您。其實audi.options.night_vision.extra_price是某種僞代碼。汽車有很多選擇,因此對每個選項進行範圍劃分並沒有多大意義。 – Roger