Mapeamento com Doctrine no Symfony

André Chaves
Code Maestro
Published in
4 min readMar 12, 2018

Todo sistema tem um momento em que a estrutura das coisas já esta bem definida e, normalmente, é aí que começamos a expansão.

Nesse momento é legal ter bastante cuidado e garantir que tudo está bem alinhado pois o processo pode ser bem repetitivo.

Relacionando entidades

Nosso sistema TikTok® já tem uma entidade, com um front-end em Bootstrap bem isolado, mas ainda faltam duas entidades bem importantes: HoraLancada e Projeto.

Seguindo os conceitos de modelagem citados quando criamos a classe Funcionario, precisamos saber o que uma HoraLancada e Projeto tem e fazem

Projeto

Em um sistema de gestão de horas, Projeto precisa ter um nome, funcionários que atuam naquele projeto e fazer o calculo do total de horas dedicadas neste projeto.

Relacionando Entidades

Aqui temos um ponto crucial. Se um Projeto tem muitos Funcionarios, precisamos representar esse relacionamento na nossa classe Projeto:

class Projeto

Perfeito, temos um atributo para guardar esses funcionários. Mas, como fazer esse relacionamento no banco de dados? Ou seja, como vamos falar pro Doctrine que precisamos aquilo representa uma coleção de funcionários?

Mapeando entidades

Da mesma forma que dizemos para o doctrine com anotações quem era o Id, o tipo dele, podemos dizer para qual entidade esse atributo funcionários aponta. Além disso, também podemos dizer se um projeto tem muitos funcionários (OneToMany) e quem representa o outro lado desse mapeamento, ou seja, qual atributo guarda o projeto de cada funcionário:

classe Projeto com funcionários

O outro lado

Perfeito, já falamos certinho qual é a entidade que está relacionada ao atributo funcionários e até apontamos quem vai guardar o projeto dentro de cada Funcionario.

Mas, precisamos criar efetivamente essa representação em Funcionário e dizer que todo funcionário tem um Projeto. E mais, precisamos indicar que muitos funcionários estão dentro de um projeto(ManyToOne) indicando a classe de destino e quem vai guardar esses funcionários lá dentro:

classe Funcionario com Projeto

Para garantir que nosso mapeamento está certinho, podemos utilizar o comando do Symfony:

php bin/console doctrine:schema:validate

comando schema validate

Outros Mapeamentos

Além desse tipo de mapeamento, temos muitos outros, como ManyToMany e OneToOne, bidirecionais e uni-direcionais. Cada caso é um caso e o melhor lugar para consultar o jeito certo de se fazer esses mapeamentos é olhando a documentação do Doctrine.

HoraLancada

Da mesma forma que um projeto tem muitos funcionários, um funcionário tem muitas HoraLancada. Ou seja, temos, de novo, um OneToMany de funcionário para HoraLancada e ManyToOne de HoraLancada para funcionário.

A mesma ideia se repete quando pensamos que todo projeto tem um total de horas lançadas! Ou seja, de novo, um Projeto tem muitas HoraLancada e uma HoraLancada está em um projeto. Mais uma vez, OneToMany.

Além disso, uma HoraLancada deve ter uma descrição, o que o funcionário fez e em quanto tempo ele gastou, em horas e minutos:

HoraLancada com relacionamentos

O outro lado

Da mesma forma que fizemos para Funcionario, agora precisamos fazer para HoraLancada. Já temos todo o mapeamento da HoraLancada mas falta indicar esse mapeamento nas entidades Funcionario e Projeto.

Mapeamento de HoraLancada em Funcionario
Mapeamento de HoraLancada em Projeto

Validando novamente nosso mapeamento com o comando:

Sabemos que está tudo certo =)

E, finalmente, para aplicar as mudanças no banco, rodamos o comando:

php bin/console doctrine:schema:update -f

Próximos passos

Agora que temos todas as entidades relacionadas, o próximo desafio (e final) será realizar as funcionalidades de Adição, Remoção, Listagem e Edição (mais conhecido como CRUD) das nossas entidades relacionadas. Para isso, vamos utilizar o FormType do symfony =)

E vocês, o que acharam do relacionamento entre entidades com o Doctrine + Symfony?

--

--

André Chaves
Code Maestro

Empreendedor, CTO, desenvolvedor e apaixonado por automação.