Here is the issue I have been dealing with all day...
I have got a superclass called 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) :
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 :
Method "amount" for object "MongoDBODMProxies__CG__\Bundle\Document\Message" does not exist.
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 ?
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.
So I tried a $get_class($bill) before and after persisting a Bill object, and that is what I got back :
My issue could come from here, don't you think ?
This is a design issue - your Dialogue
holds a collection of Messages
, which do not anything about being subclassed or not.
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.:
Bundle\Document\Dialogue:
...
referenceMany:
messages:
targetDocument: Message
cascade: [remove]
bills:
targetDocument: Bill
cascade: [remove]
...
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 %}