蒙古语嵌入关系中的实际多态性 [英] real polymorphism in embed relations in mongoid

查看:65
本文介绍了蒙古语嵌入关系中的实际多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Mongoid3,我正在尝试将多态性添加到我的嵌入关系中.

Using Mongoid3, I'm trying to add polymorphism to my embedded relations.

我有一个类Item,该类必须 embed_one 对象包含我的信息. 达成的协议是:
-我的对象的类型可以是以下类型之一:CalendarStickerPicture;
-无论对象的类型如何,我都希望通过唯一的键"进行访问:详细信息
例如:

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  

将我的PictureCalendarSticker保留为类实例的

(因为保存后每种方法都有不同的应用方法).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆