2016-04-02 12 views
0

車(例えば、アウディ、メルセデス)とオプション(ABS、レーザーヘッドライト、ナイトビジョン...)の2つのモデルを持っています。車のhabtmオプション。モンゴイドモデルのトリッキーな延長

AudiとMercedesの両方に「Night Vision」オプションがあるとします。 しかしメルセデスでは、このオプションのためにいくらかの余分なお金を支払う必要があります。私が推測しているように、私は何とか私のオプションモデルをいくつかの車のオプションの余分な価格を格納するために拡張する必要があります。車のモデル私はまた修正されるべきだと思います。しかし、どのように想像することはできません。

このような行動に何かを達成するために私の目的:

Audi.options.night_vision.extra_price =>

nilの

Mercedes.options.night_vision.extra_price =>私はドンもちろん

300」をすべての車のオプションコレクションで「ナイトビジョン」オプションを複製したい

ありがとうございました。

+0

audi.options.night_vision.extra_price(アウディ)はありませんエレガントなソリューション – Roger

答えて

0

これは最も簡単ではなく、最もエレガントでもなく、オプションの実装方法に関する前提に基づいて動作するアイデアでもありません。もっと助けが必要な場合は、私に戻ってください。

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 

上記の仮定が正しい場合は、次のようなモデルを持っていることを私は仮定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

あなたは解決策を思いつきました。あなたが誤解を招いて申し訳ありませんが、audi.options.first.extra_price – ABrowne

+0

ではなく、audi.options.night_vision.extra_priceを行うことができるように、あなたが.night_visionの範囲を望むため、この方法はお勧めしませんでした。実際、audi.options.night_vision.extra_priceは何らかの擬似コードでした。車にはたくさんのオプションがあるので、各オプションの有効範囲はあまり意味がありません。 – Roger