2016-04-02 126 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