1

I know this question seems horrible at first glance.

This is what I have:

I have part of my model stored in *.yaml file and loaded when it's needed. Let's call it StaticObject. It have 10 or so objects, is not scaleable by design and read-only. Each StaticObject has own ID and I can get object with given ID from service in container, like:

$container->get('static_object_repository')->getById('foo');

Now I have some entity which has "association" with that StaticObject. I want it to be stored in database as ID, so I added new field $staticObjectId to entity, like this:

class MyEntity
{
    //...

    /**
     * @ORM\Column(type="string", name="static_object_id")
     */
    protected $staticObjectId;

    //...
}

Now every time I want to get StaticObject from entity, I call service from my container, like:

$staticObject = $container->get('static_object_repository')->getById($entity->getStaticObjectId());

and when I want to change that associated object, I do something like:

$entity->setStaticObjectId($staticObject->getId());

I hope you got enough information about my code. Tell me if I miss something important for you to understand problem.

This is what I want:

I want to store StaticObject instance directly in entity, so I can simply get and set it. Just simple

$entity->getStaticObject();
//and
$entity->setStaticObject($staticObject);

My first thought was to hide all needed transformation in getter and setter. So I get:

class MyEntity 
{
    //...

    public function setStaticObject(StaticObject $so)
    {
        $this->staticObjectId = $so->getId();
    }

    public function getStaticObject()
    {
        return $container->get('static_object_repository')->getById($this->staticObjectId);
    }

    //...
}

But wait... I cannot have container in my model. Doesn't I? I can find nowhere how to inject container/service to entity.

My second thought was to use custom Doctrine mapping type. And again - you cannot inject service to it (since custom type is class and no object/service). I did everything from this section of Doctine2 documentation and i read this section in Symfony2 cookbook, but I cannot see solution.

How can I do this?

tereško
  • 58,060
  • 25
  • 98
  • 150
Damian Polac
  • 911
  • 9
  • 20

3 Answers3

2

you can set up a listener on prePersist, preUpdate, ..., and then inject the service in it via the service configuration

the docs are awesome

ROLO
  • 581
  • 4
  • 13
2

It's generally a good idea to build Entity relationships as they leave the ORM architecture and before they reach the everyday application layer. The best way to do this would be keep the Entity simple:

class MyEntity
{
    public function setStaticObject(StaticObject $so)
    {
        $this->staticObject = $so;
    }

    public function getStaticObject()
    {
        return $this->staticObject;
    }
}

and use a custom Hydrator to set the StaticObject right after the row is loaded:

https://www.techpunch.co.uk/development/create-custom-doctrine2-hydrator-symfony2

If lazy-loading is important, then it isn't a huge step to use custom Hydration to inject a StaticObjectFactory class, which you could use like this:

// MyEntity
public function getStaticObject()
{
    if (!isset($this->staticObject)) {
        $this->staticObject = $this->staticObjectFactory->loadById($this->getStaticObjectId());
    }

    return $this->staticObject
}
Mathew
  • 8,203
  • 6
  • 37
  • 59
0

What you should do is something like:

public function getStaticObject($staticObjectRepository)
{
    return $staticObjectRepository->getById($this->staticObjectId);
}

Of course you could also search for other answers to this question. For example: Injectiong or accessing service container within an entity object

Community
  • 1
  • 1
Cerad
  • 48,157
  • 8
  • 90
  • 92