1
比方說,我有一個Order
模型,其中包含許多products
。我希望能夠跟蹤哪些產品已發貨,哪些未發貨,因此我想跟蹤與每個關係一起發佈的一些元數據。如果這是一個has_one
關係,那麼它會很簡單,只需插入更多的字段。Mongoid has_many元數據
我怎樣才能做到這一點與Order
模型,並用乾淨的一個Mongoid模型Product
之間的關係has_many
?
比方說,我有一個Order
模型,其中包含許多products
。我希望能夠跟蹤哪些產品已發貨,哪些未發貨,因此我想跟蹤與每個關係一起發佈的一些元數據。如果這是一個has_one
關係,那麼它會很簡單,只需插入更多的字段。Mongoid has_many元數據
我怎樣才能做到這一點與Order
模型,並用乾淨的一個Mongoid模型Product
之間的關係has_many
?
我自己解決了這個問題,我使用另一個模型OrderProduct
作爲兩者之間的代理。該州的實施是使用state_machine
寶石完成的。我最終在Order模型中包裝了很多對產品狀態機的調用。這允許我在訂單實例上調用諸如.product_state(product)
或can_cancel_product?(product)
的東西。
訂購
class Order
include Mongoid::Document
include Mongoid::Timestamps
field :state, type: String
embeds_many :order_products
state_machine initial: :open do
...
end
def products
order_products.map do |op|
op.product
end.freeze
end
def add_product(product)
OrderProduct.create({_product: product._id, order: self})
end
def remove_product(product)
order_products.delete find_order_product(p)
end
#wrapper for product events
OrderProduct.new.state_paths.events.each do |event|
define_method "#{event}_product" do |product|
find_order_product(product).send(event)
end
define_method "can_#{event}_product?" do |product|
find_order_product(product).send("can_#{event}?")
end
end
#wrapper for product states
OrderProduct.state_machine.states.map(&:name).each do |state|
define_method "product_#{state}?" do |product|
find_order_product(product).send("#{state}?")
end
end
#wrapper for product current state
def product_state(product)
find_order_product(product).state
end
private
def find_order_product(p)
order_products.at(order_products.index do |op|
op.product == p
end)
end
end
OrderProduct
class OrderProduct
include Mongoid::Document
embedded_in :order
field :_product, type: Moped::BSON::ObjectId
state_machine initial: :open do
....
end
def product
Product.find(_product)
end
def product=(product)
_product = (product._id)
end
end