2015-11-07 81 views
0

我有這樣的定義Mongoid類(不相關的領域留下了爲簡潔起見):如何正確嵌入mongoid文檔的副本到父代?

class Product 
    include Mongoid::Document 

    belongs_to :category 
end 

class Order 
    include Mongoid::Document 

    embeds_many :order_items 
end 

class OrderItem 
    include Mongoid::Document 

    embeds_one :product 
    embedded_in :order 

    field :count, type: Integer 
end 

這意味着,我把產品分類收集與當用戶進行購買,我要將所有產品副本她在訂單文檔中購買(所以我有一個她購買的確切項目的快照,未來的編輯不會改變已經購買的產品)。 這是製作嵌入式副本的正確方法,還是應該更改模式?例如,創建新的文檔類,如EmbeddedProduct,並複製Product的相關字段?

目前的解決方案似乎工作,但從我在文檔和論壇中閱讀的文檔看來,文檔應該嵌入或分開收集,而不是兩者。

回答

0

這個問題似乎沒有得到任何關注:)

反正我想通去將不嵌入在order_item產品的最佳方式,但是從產品的複製相關領域order_item。

解決方案看起來像這樣

class Product 
    include Mongoid::Document 

    # product fields like name, price, ... 

    belongs_to :category 
end 

class Order 
    include Mongoid::Document 

    # order fields like date, total_amount, address ... 

    embeds_many :order_items 
end 

class OrderItem 
    include Mongoid::Document 
    include Mongoid::MoneyField 

    embedded_in :order 

    # you can also store reference to original product 
    belongs_to :original_product 

    field :count, type: Integer 
    field :name 
    field :ean 
    field :sku 
    money_field :final_price 

    def self.from_product(product) 
    item = self.new 
    # ... assign fields from product, eg: 
    # item.name = product.name 

    item 
    end 
end 

而當用戶點擊「添加到購物車」,你可以做這樣的事情:通過可視發生了什麼

def add 
    # check if product is already in the cart 
    order_item = @order.items.detect {|item| item.product_id == params[:product_id]} 

    # if not, create from product in database 
    if order_item.nil? 
    product = Product.find(params[:product_id]) 
    order_item = OrderItem.from_product(product) 

    # and add to items array 
    @order.items.push(order_item) 
    end 

    # set count that we got from product form 
    # (we can do this since order_item is 
    # also reference to the order_item inside array of order_items) 
    order_item.count = params[:count] 

    # emit event 
    event = Events::CartItemChanged.new(order_item: order_item, order: @order, request_params: params) 
    broadcast :cart_item_changed, event 

    # no need to call validations since we're just adding an item 
    @order.save! :validate => false 

    redirect_to cart_path 
end 
+0

牛肉這了一點,然後隨時接受你自己的答案。 –