2016-04-02 27 views
0

İki modele sahip: Otomobil (örneğin Audi, Mercedes) ve Opsiyon (ABS, Lazer Far, Gece Görüş ...). Araba habtm seçenekleri.Uzun ömürlü mongoid modelinin uzatılması

Hem Audi hem de Mercedes için "Gece Görüşü" seçeneği varsayalım. Ama Mercedes’e sahip olmak için bu seçenek için ekstra para ödemeniz gerekiyor. Tahmin ettiğim gibi, bir şekilde benim seçenek modelimin bazı otomobiller için ekstra fiyatını saklamak için genişletmem gerekiyor. Bence araba modeli de değiştirilmeli. Ama nasıl olduğunu hayal edemezsin.

böyle davranış şey elde etmek Amacım:

Audi.options.night_vision.extra_price =>

nil

Mercedes.options.night_vision.extra_price => ı don Tabii

300' Her araç için seçenekler koleksiyonunda "Gece Görüşü" seçeneğini çoğaltmak istiyorum.

Teşekkürler.

+0

audi.options.night_vision.extra_price (audi) ancak zarif çözüm – Roger

cevap

0

Bu, en basit veya en zarif olanı, yalnızca seçenekleri nasıl uygulayabileceğinizle ilgili varsayımlara dayanarak çalışması gereken bir fikir değildir. Daha fazla yardıma ihtiyacınız varsa lütfen bana dönün.

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 

Bu yapmanı sağlayacak:

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

yukarıdaki varsayımlar doğruysa

Sana gibi bir model olduğunu varsayalım audi.options.night_vision.extra_price ulaşmak için , bunu sevdiği sınıfları mod gerekir:

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 

Bu o zaman imkan vermelidir gibi seçenekleri doldurmak için: Bir araba night_vision bulmak girişiminde eğer

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 

Ve bu alacağı night_vision yoktu:

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

Benim çözümüm: http://pastebin.com/ZgrJtEa3 – Roger

+0

Size bir çözüm buldunuz sevindim. Audi.options.first.extra_price – ABrowne

+0

sizi yanıltmak için üzgün yerine audi.options.night_vision.extra_price yapabilmeniz için .night_vision kapsamını istediğiniz için bu şekilde tavsiye etmedim. Aslında audi.options.night_vision.extra_price bir çeşit sahte koddu. Arabalar, her seçeneğin kapsamının çok anlamlı olmadığı için çok sayıda seçeneğe sahiptir. – Roger