2015-11-07 83 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

牛肉这了一点,然后随时接受你自己的答案。 –