Symfony Form Types

André Chaves
Code Maestro
Published in
6 min readMar 19, 2018

Criar um CRUD costuma ser bem simples. Mas, pode não ser quando temos muitos relacionamentos entre as entidades.

No caso do TikTok®,como criar um formulário que permita seleção de Funcionarios em HoraLancada? Ou até mesmo de Projeto em HoraLancada?

Mãos na massa

Agora que temos todos os mapeamentos bem definidos, precisamos de alguma tela que consiga cadastrar, listar, editar e persistir Projetos e HorasLancadas no banco de dados.

Todas essas funcionalidades precisarão estar bem separadas, certo? Por isso teremos um controller para cada entidade.

Projeto Controller

Criar e mostrar não é nenhuma novidade, precisamos das actions mostra(), formulario() e cria():

Actions no ProjetoController

Listagem

Para listar todos, vamos precisar de uma rota nova, por exemplo:

/**
*
@Route("/projeto/lista",methods="GET")
*/
public function lista()

E, dentro dela, precisamos pedir para o Doctrine todos os posts cadastrados no banco. Para realizar essas funcionalidades de busca o Symfony disponibiliza um repositório onde podemos buscar o que quisermos!

$repository = $this->getDoctrine()->getManager()->getRepository(Projeto::class);

Aqui estamos pedindo um repositório para a classe Projeto, já que é ela que queremos listar. Em seguida, basta devolver pra View todos os projetos do banco com o método findAll:

Action lista

Remoção

Para remover, basta a gente pedir pro Doctrine remover e criar uma action que pegue o projeto em questão:

Depois de remover, voltamos para a listagem de projetos com o redirect =)

Edição

Ao editar um Projeto, precisamos conseguir mudar o nome dele e os funcionários associados a esse projeto. Isso significa que no nosso controller, temos que conseguir adicionar e remover funcionários da lista de funcionarios do projeto.

Além disso, precisamos garantir que sempre vai existir uma lista de Funcionarios nesse projeto, mesmo que vazia. Uma abordagem seria criar um array no construtor e atribuir a funcionários.

Mas, o próprio Doctrine tem uma classe para lidar com coleções de entidades relacionadas!

garantindo uma coleção no construtor de Projeto
métodos de adição e remoção de funcionario na classe Projeto

Criando os formulários

Além de criar métodos para adicionar e remover funcionários, precisaremos de uma tela para que o cliente realmente consiga selecionar esses funcionários. Para isso, precisaríamos buscar do banco de dados todos os funcionários e fazer uma listagem.

E não para por aqui, precisaríamos receber esses dados no controller. Chamar os métodos para atualizar os relacionamentos.

Tem bastante trabalho envolvido ao gerar formulários para entidades que possuem relacionamentos.

Problemas de manutenção

Caso a entidade mudasse e o relacionamento deixasse de existir ou mudasse o tipo do relacionamento, precisaríamos botar a mão em toda aquela estrutura necessária no controller e no front.

Gerenciando entidades com Form Type

Para resolver todos esses problemas relacionados a formulário, como renderizar na view, quais atributos devem aparecer no formulário ou não. Verificar validação e muito mais, o Symfony vem com um construtor de formulários!

Assim, só precisamos criar o formulario e utilizá-lo tanto no back-end quanto no front-end!

Para instalar o componente de formulários no Symfony, basta chamar o composer:

comando composer require form

Vamos começar criando o formulário de edição na action mostra(). Para isso, basta pedir para o próprio controller o formBuilder:

Tendo o builder na mão, podemos dizer quais campos do projeto queremos no nosso form com o método add(). Qualquer campo que não passarmos pelo add, não será considerado no form.

Além disso, também podemos definir a action, com o método setAction() e até mesmo o método do formulário com o método setMethod()!

Depois de construir o formulário, precisamos renderiza-lo na view. Por isso mandamos para o método render o novo valor “form” =)

Renderizando o Form no Twig

Agora que temos toda a definição do form pronta no nosso Twig, podemos pedir para que o próprio Twig renderize todo o formulário com apenas 3 chamadas:

  • FormStart() para abrir a tag form
  • FormWidget() para processar todos os campos do formulário
  • FormEnd() para fechar a tag form

Aplicando esses 3 no nosso Twig, temos:

renderizando o formulário no twig

Cada um dos métodos recebe como parâmetro justamente aquele form que criamos no controller! No nosso caso, demos o nome dele de form, mas poderia ser qualquer coisa =)

Se dermos uma olhada na nossa view renderizada, temos:

view de edição de projeto

Além do campo nome, uma listagem onde podemos selecionar quantos funcionários quisermos, já puxando direto do banco!

Recebendo dados da view

Perfeito, conseguimos criar um formulário com o relacionamento. Mas, ainda falta puxar esses dados da view e mandar pro banco. Para isso, temos a action edita() que é destino nosso form.

A primeira coisa que precisamos fazer, é justamente montar o formulário:

form builder na action edita

Tendo o formulário pronto, basta pedirmos pra que ele mesmo olhe no request os dados que precisam ser settados, com o método handleRequest()!

handle request

Sim, depois dessa chamada, o próprio Symfony já populou toda a entidade Projeto com os dados que vieram do formulário =)

Validando

Além de receber todos os dados da view, podemos utilizar nosso form do back-end para validar a entidade com o método isValid():

chamando isValid do form

Assim, se rolar algum erro não entramos no if e, por consequência, voltamos pra tela de edição com o mesmo projeto.

Agora que temos certeza que nossos dados estão validos, podemos atualizar os relacionamentos e mandar tudo pro banco de dados:

atualizando os relacionamentos e executando os merges

E pronto! Conseguimos editar nossa entidade Projeto e os relacionamentos dela com Funcionario, sem precisar buscar absolutamente nada do request diretamente.

Finalizando o projeto

Agora que conseguimos gerar todos os formulários no back-end, basta repetir o mesmo processo em todas as nossas actions.

Inclusive, agora o processo já é bem claro. Toda entidade que surgir no sistema, passará pela modelagem, a criação do controller com CRUD(criar, listar, atualizar e deletar), formType para gerenciar os dados e Twig para renderizar nossas Views =)

A parte mais importante em utilizar boas ferramentas, como o Symfony, o Doctrine, o Twig entre outras que comentamos nos últimos posts é justamente ter um bom processo pelo qual passamos toda nova funcionalidade no sistema.

Se toda feature é feita com ferramentas que garantem o desacoplamento e andam com as boas práticas, ganhamos a tendência de desenvolvê-la com o mesmo preceito!

Proximos passos

Agora que nosso sistema TikTok® está finalmente pronto, com injeção de dependências, template views, formTypes e tudo que a base do Symfony nos oferece de bom, no próximo post faremos o deploy dessa aplicação na Digital Ocean!

Um serviço bem famoso de locação de máquinas com acesso ssh que funciona muito bem e de forma bem parecida com todos os outros prestadores de serviço desse tipo como Amazon!

E ai, quer saber mais sobre FormTypes? Da uma olhada no post sobre validação com Event Listeners e Form Themes!

Ah! O código pronto dessa saga de posts está disponível no meu git =)

--

--

André Chaves
Code Maestro

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