如何链接到 MongoMapper 中的 EmbeddedDocument?
我对此架构设计不是很有信心(欢迎提出建议),但我有两个集合:
- Business
- Customer
,每个集合都包含嵌入文档:
- Businesses 包含 Events
- Customers 包含 Registrations
类定义如下,但首先是问题。当我创建业务并添加事件时,一切看起来都很好。当我创建客户并添加注册时,一切看起来都很好。此时,我可以做到:
ruby-1.9.2-p180 :380 > customer1.registrations.first.customer
=> #<Customer _id: BSON::ObjectId('4eb22a5bbae7a01331000019'), business_id: BSON::ObjectId('4eb215a9bae7a01331000001'), registrations: nil>
完美!但是然后...我使用 event1.registrations << 将注册添加到事件中Registration1,现在 event1
有一个不同的 customer
参考,具体取决于我是通过活动还是通过客户访问它:
ruby-1.9.2-p180 :444 > customer1.registrations.first.customer
=> #<Customer _id: BSON::ObjectId('4eb22a5bbae7a01331000019'), business_id: BSON::ObjectId('4eb215a9bae7a01331000001'), posts: nil>
ruby-1.9.2-p180 :445 > business1.events.first.registrations.first.customer
=> #<Event _id: BSON::ObjectId('4eb21ab2bae7a0133100000f'), business_id: BSON::ObjectId('4eb215a9bae7a01331000001'), posts: nil>
ruby-1.9.2-p180 :446 > business1.events.first.registrations.first == customer1.registrations.first
=> true
不完美......我最好的猜测 registration1
的重复项已嵌入到 customer1
和 event1
中?我想要的是活动与其许多注册(由客户拥有并嵌入)之间的链接。这个模式可以吗?
这就是我的模型的样子。它们都有未显示的附加(且不相关)键:
class Business
include MongoMapper::Document
many :events
many :customers
end
class Event
include MongoMapper::EmbeddedDocument
embedded_in :business
many :registrations
end
class Customer
include MongoMapper::Document
belongs_to :business
key :business_id, ObjectId
many :registrations
end
class Registration
include MongoMapper::EmbeddedDocument
embedded_in :customer
belongs_to :event
key :event_id, ObjectId
end
I'm not very confident about this schema design (suggestions welcome), but I have two collections:
- Business
- Customer
and each of them contains embedded documents:
- Businesses contain Events
- Customers contain Registrations
The class definitions are below, but first, the question. When I create a Business and add an Event, everything looks fine. When I create a Customer and add a Registration, everything looks fine. At this point, I can do:
ruby-1.9.2-p180 :380 > customer1.registrations.first.customer
=> #<Customer _id: BSON::ObjectId('4eb22a5bbae7a01331000019'), business_id: BSON::ObjectId('4eb215a9bae7a01331000001'), registrations: nil>
Perfect! But then... I add the Registration to the Event using event1.registrations << registration1
, and now event1
has a different customer
reference depending on whether I access it through the Event or through the Customer:
ruby-1.9.2-p180 :444 > customer1.registrations.first.customer
=> #<Customer _id: BSON::ObjectId('4eb22a5bbae7a01331000019'), business_id: BSON::ObjectId('4eb215a9bae7a01331000001'), posts: nil>
ruby-1.9.2-p180 :445 > business1.events.first.registrations.first.customer
=> #<Event _id: BSON::ObjectId('4eb21ab2bae7a0133100000f'), business_id: BSON::ObjectId('4eb215a9bae7a01331000001'), posts: nil>
ruby-1.9.2-p180 :446 > business1.events.first.registrations.first == customer1.registrations.first
=> true
Not perfect.... my best guess is that duplicates of registration1
have been embedded in both customer1
and event1
? What I wanted was links between the Event and its many Registrations (which are owned and embedded in Customers). Is that possible with this schema?
This is what my models look like. They all have additional (and irrelevant) keys that are not displayed:
class Business
include MongoMapper::Document
many :events
many :customers
end
class Event
include MongoMapper::EmbeddedDocument
embedded_in :business
many :registrations
end
class Customer
include MongoMapper::Document
belongs_to :business
key :business_id, ObjectId
many :registrations
end
class Registration
include MongoMapper::EmbeddedDocument
embedded_in :customer
belongs_to :event
key :event_id, ObjectId
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的。
Registration
是一个MongoMapper::EmbeddedDocument
因此它始终是嵌入的。这意味着,由于Customer
和Event
都有许多:registrations
,因此每个注册对象中都会嵌入不同的注册对象。在 MongoMapper 中,
embedded_in :customer
只是为customer
方法添加别名以返回文档的父级。这只是一种更奇特的调用_parent_document
的方式。这就是为什么您的活动注册客户是一个活动对象。 (在此处查看源代码)。经验法则是仅在子总是被使用时嵌入在其父级的上下文中。
Yep.
Registration
is aMongoMapper::EmbeddedDocument
so it's always embedded. That means because bothCustomer
andEvent
havemany :registrations
, different registration objects will be embedded in each.In MongoMapper, the
embedded_in :customer
just alias acustomer
method to return the document's parent. It's just a fancier way of calling_parent_document
. That's why your event's registration's customer is an event object. (See source here).The rule of thumb is to only embed when the child will always be used in context of its parent.