symfonydoctrine

How to refer an entitiy from another entity


Assuming I have a parent entity:

#[ORM\Entity(repositoryClass: EventRepository::class)]
class EventEntity
{
    ...
    #[ORM\ManyToOne(targetEntity: EventStatusEntity::class)]
    #[ORM\JoinColumn(name: 'status_id', referencedColumnName: 'id')]
    private EventStatusEntity $status;

    public setStatusDraft()
    {
         $this->setStatus(...?? (1) ??...); // DRAFT status has a pre-determined ID="1"
    }
    ...
}

How can I implement setStatusDraft? Should I inject a entityManager and use getReference, or inject EventStatusRepository and use findOneById?

To me, it seems quite a common scenario, though, I found no answers so far. I know that I should probably introduce a service layer, but this task does not worth the effort. I'd very much prefer to add this simple functionality to the Doctrine entity.


Solution

  • Entities should be as "simple" as possible. Avoid injecting services such as EntityManager in entities.

    I would argue against the assumption that a simple service is overkill.

    You may only be setting the status in one place at this moment, but what if you want to set the status elsewhere in the future? Having a service where you can simply do (from anywhere in your code);

    $this->eventStatusService->setStatusDraft('draft');
    

    Is easier, faster, better maintainable and doesn't go against best practices. As an example, it took a few seconds to write the service below, less time than it takes to open StackOverflow and write a new question.

    class EventStatusService
    {
        public function __construct(private EntityManagerInterface $entityManager) {}
    
        public function setStatusDraft(EventEntity $event): void
        {
            $draftStatus = $this->entityManager->getReference(EventStatusEntity::class, 1);
            $event->setStatus($draftStatus);
        }
    }
    

    For more info on Doctrine relations, setting-and-fetching data, see Symfony's docs: https://symfony.com/doc/current/doctrine/associations.html#more-information-on-associations