Symfony2 - 呈现被引用为超类实例

时间:2015-05-07 17:01:21

标签: php mongodb symfony inheritance

以下是我整天处理的问题......

我有一个名为Message的超类:

class Message
{   

protected $id;

protected $body;

protected $sender;

protected $receiver;

// [...]

从中继承我的班级Bill

class Bill extends Message
{
protected $id;

protected $amount;

我想创建一个Dialogue类来收集几条消息(比如账单):

class Dialogue
{
protected $id;

protected $subject;

protected $messages = array();

这是相应的映射(YAML,Mongodb):

Bundle\Document\Dialogue:
repositoryClass: Bundle\Repository\DialogueRepository
fields:
    id:
        id:  true
    subject:
        type: string
referenceMany:
    messages:
        targetDocument: Message
        cascade: [remove]

问题是,当我尝试渲染某些特定于Bill的属性时(例如,在Twig中:dialogue[0].messages.amount),我收到此错误:

  

对象“MongoDBODMProxies__CG __ \ Bundle \ Document \ Message”的方法“amount”不存在。

我想我已经明白我的账单被视为一条消息,而不是一条账单...此外,我认为在PHP中可能无法进行类型转换,以确保{{1}被视为一项法案......如何才能访问这些特定属性?

帮助:(

PS:我可能有一个提示:当我从相应的存储库加载对话框对象时会发生此错误。但是,如果我在控制器中创建一个新的Dialogue和一个新的Bill并直接渲染它们,那么一切都能正常工作。

所以我在持久化Bill对象之前和之后尝试了$ get_class($ bill),这就是我得到的:

  • 在持久化之前:Bundle \ Document \ Bill
  • 从repo中持久+加载后:MongoDBODMProxies__CG __ \ Bundle \ Document \ Message

我的问题可能来自这里,你不觉得吗?

2 个答案:

答案 0 :(得分:1)

这是一个设计问题 - 您的Dialogue拥有Messages的集合,它与子类别无关。

要么为所有Message类型提供一个公共Interface,它具有您需要的所有可访问属性,要么为您的Dialogue实体明确提供每种类型的单独关系要分配给Message,例如:

Bundle\Document\Dialogue:
...
referenceMany:
    messages:
        targetDocument: Message
        cascade: [remove]
    bills:
        targetDocument: Bill
        cascade: [remove]
    ...

答案 1 :(得分:0)

dialogue[0].messages[0].amount

由于消息是一个数组,但您尝试将其作为对象访问,或

{% for message in dialogue[0].messages %}
    {{ message.amount }}
{% endfor %}