Symfony2 - 呈现作为超类实例引用的对象的子类属性

时间:2022-10-16 18:15:53

Here is the issue I have been dealing with all day...

这是我一直在处理的问题......

I have got a superclass called Message :

我有一个名为Message的超类:

class Message
{   

protected $id;

protected $body;

protected $sender;

protected $receiver;

// [...]

from which inherits my class Bill :

继承我的班级比尔:

class Bill extends Message
{
protected $id;

protected $amount;

And I wanted to create a Dialogue class that gathers several messages (for instance bills) :

我想创建一个收集几条消息的对话类(例如账单):

class Dialogue
{
protected $id;

protected $subject;

protected $messages = array();

And here is the corresponding mapping (YAML, Mongodb) :

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

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

The problem is, when I try to render some attributes specific to Bill (for instance, in Twig : dialogue[0].messages.amount), I get this error :

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

Method "amount" for object "MongoDBODMProxies__CG__\Bundle\Document\Message" does not exist.

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

I think I have understood that my bill is considered as a Message, and not a Bill... Furthermore, I don't think it is possible tu typecast, in PHP, in order to make sure that dialogue.message[0] is considered as a Bill... What can I do to access these specific attributes ?

我想我已经明白我的账单被认为是一条消息,而不是一条账单...此外,我认为在PHP中,为了确保对话。消息[0]是可能的。被视为一项法案......我可以做些什么来获取这些特定属性?

Help :(

PS : I may have a hint : this error occurs when I load dialogues objects from the corresponding repository. However, if I create a new Dialogue and a new Bill in a controller and render them directly, everything works correctly.

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

So I tried a $get_class($bill) before and after persisting a Bill object, and that is what I got back :

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

  • before persisting : Bundle\Document\Bill
  • 在坚持之前:Bundle \ Document \ Bill

  • after persisting + loading from the repo : MongoDBODMProxies__CG__\Bundle\Document\Message
  • 从repo持久+加载后:MongoDBODMProxies__CG __ \ Bundle \ Document \ Message

My issue could come from here, don't you think ?

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

2 个解决方案

#1


This is a design issue - your Dialogue holds a collection of Messages, which do not anything about being subclassed or not.

这是一个设计问题 - 您的Dialogue包含一组消息,这些消息与子类无关。

Either you provide all your Message types with a common Interface, that has all the accessible properties you need, either you explicitly provide your Dialogue entity with a separate relation for every type of Message you want to assign to it, e.g.:

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

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

#2


try

dialogue[0].messages[0].amount

As messages is an array, but you try to access it as an object, or

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

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

#1


This is a design issue - your Dialogue holds a collection of Messages, which do not anything about being subclassed or not.

这是一个设计问题 - 您的Dialogue包含一组消息,这些消息与子类无关。

Either you provide all your Message types with a common Interface, that has all the accessible properties you need, either you explicitly provide your Dialogue entity with a separate relation for every type of Message you want to assign to it, e.g.:

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

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

#2


try

dialogue[0].messages[0].amount

As messages is an array, but you try to access it as an object, or

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

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