蒙古语嵌入关系中的实际多态性 [英] real polymorphism in embed relations in mongoid
问题描述
使用Mongoid3,我正在尝试将多态性添加到我的嵌入关系中.
Using Mongoid3, I'm trying to add polymorphism to my embedded relations.
我有一个类Item
,该类必须 embed_one 对象包含我的信息.
达成的协议是:
-我的对象的类型可以是以下类型之一:Calendar
,Sticker
,Picture
;
-无论对象的类型如何,我都希望通过唯一的键"进行访问:详细信息
例如:
I have a class Item
that must embed_one object containing my informations.
The deal is that :
- my object's type can be one of those : Calendar
, Sticker
, Picture
;
- regardless my object's type, I want to access it by a unique 'key' : detail
e.g. :
pry> my_item1.detail
=> `<Picture _id: 1234>`
pry> my_item2.detail
=> `<Sticker _id: 8964>`
pry>
首先,我尝试使用如下所述的关键字 as 和 polymorphic : https://github.com/mongoid/mongoid/issues/902
例如:
First, I tried using the keywords as and polymorphic like described here: https://github.com/mongoid/mongoid/issues/902
e.g. :
class Item
include Mongoid::Document
embeds_one :detail, as: :item_slot
end
class Picture
include Mongoid::Document
embedded_in :item_slot, polymorphic: true
end
class Calendar
include Mongoid::Document
embedded_in :item_slot, polymorphic: true
end
class Sticker
include Mongoid::Document
embedded_in :item_slot, polymorphic: true
end
然后,我尝试访问我的详细信息,但不幸的是,我收到此消息错误:
Then I'm trying to access to my detail but unhappily, I got this message error :
pry(main)> i = Item.new
pry(main)> i.detail
=> nil
pry(main)> i.detail = Picture.find('50b864').dup
pry(main)> i.save
=> true
pry(main)> i = Item.find i._id
pry(main)> i.detail
NameError: uninitialized constant Detail
from /home/jg/.rvm/gems/ruby-1.9.3-p448/gems/activesupport-3.2.14/lib/active_support/inflector/methods.rb:230:in `block in constantize'
它说mongoid在我的item
中找不到任何.detail
.为什么不.
It says mongoid didn't find any .detail
into my item
. Why not.
然后,我发现此主题 mongoid多态关联错误告诉要添加 class_name .所以我像这样更新了我的代码:
Then, I found this topic mongoid polymorphic association error telling to add class_name. So I updated my code like so :
class Item
include Mongoid::Document
embeds_one :detail, class_name: "Picture", class_name: "Calendar", class_name: "Sticker"
end
让我们尝试一下:
pry(main)> i.detail = Picture.find('50b864').dup
pry(main)> i.save
=> true
pry(main)> i = Item.find i._id
pry(main)> i.detail
=> #<Sticker _id: 52961d>
这很尴尬,因为我期望得到一个Picture
,而不是一个Sticker
(里面有我的照片的值). (如果将每个不同的 class_name 值放在新行上,结果将是相同的.)
That's embarrassing because I was expecting to get a Picture
, not a Sticker
(it has my picture's values inside). (The result is the same if I put each different class_name value on new lines.)
第三次尝试时,我使用了自定义关系名称,例如所以:
For my third try, I used Custom Relation Names like so :
class Item
include Mongoid::Document
embeds_one :detail, class_name: "Picture", class_name: "Calendar", class_name: "Sticker", inverse_of: :item_slot
end
class Picture # for Calendar and Sticker too ofc
include Mongoid::Document
embedded_in :item_slot, polymorphic: true, inverse_of: :detail
end
但是它也给了我一个贴纸.
我什至尝试过:
But it gave me a Sticker too.
I even tried :
class Item
include Mongoid::Document
embeds_one :detail, inverse_of: :item_slot
end
但是它再次向我发送了先前看到的NameError.
But it send me again the NameError seen previously.
我最后的尝试是使用继承:
My last try was to use inheritance :
class Item
include Mongoid::Document
embeds_one :detail
end
class Detail
include Mongoid::Document
embedded_in :item
end
# Same again for Calendar and Sticker
class Picture < Detail
... # regular other fields
end
但是当我在 pry 中吃了sticker.rb和calendar.rb
But it gives me awful messages when lunching pry for sticker.rb and calendar.rb
DEVEL - Failed to load .../models/sticker.rb; removing partially defined constants
DEVEL - Problem while loading .../models/sticker.rb: uninitialized constant Detail
我不知道了..
==>有任何技巧吗?
I have no more idea..
==> Have anyone a tips ?
编辑:
像这里提取`Moped: :Ruby中的:BSON :: Document`属性,然后这样做:
EDIT :
It would be nice to have an equivalent to Hash[e.attributes]
like here Extract `Moped::BSON::Document` attributes in Ruby hash and then do like so :
class Item
include Mongoid::Document
field :detail
end
将我的Picture
,Calendar
和Sticker
保留为类实例的
(因为保存后每种方法都有不同的应用方法).
that keep my Picture
, Calendar
and Sticker
as class instances (because I have different methods for each to apply after saving).
JG
另一种方法
编辑2014年8月8日,将该部分拆分为该主题的答案.
Alternative way
edit 08/08/2014, split that part as the answer of that topic.
推荐答案
您应同时使用具有多态关系的继承 在这里,您去了:
You should use inheritance both with polymorphic relation Here you go:
基类
class Resource
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :resoursable, polymorphic: true
end
孩子
class Photo < Resource
field :width, type: Integer
field :height, type: Integer
end
class Video < Resource
field :url, type: String
end
嵌入
class Post
include Mongoid::Document
include Mongoid::Timestamps
embeds_one :media, as: :resoursable, class_name: 'Resource'
end
代码
p = Post.last
resource = Photo.new
p.media = resource
p.save!
这篇关于蒙古语嵌入关系中的实际多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!