Alura > Cursos de Programação > Cursos de PHP > Conteúdos de PHP > Primeiras aulas do curso Laravel: validando formulários, usando sessões e definindo relacionamentos

Laravel: validando formulários, usando sessões e definindo relacionamentos

Usando o framework - Apresentação

Boas-vindas ao curso, sou o Vinícius Dias e vou guiar vocês nessa segunda parte do treinamento de Laravel.

Então, no treinamento anterior, começamos a criar um sistema para guardar as séries, quais séries já assistimos. Agora, nesse treinamento, além de aprender vários detalhes do framework, vamos incrementar um pouco nessa aplicação.

Então, por exemplo, ao adicionar uma série, eu posso informar também quantas temporadas ela tem, e quantos episódios cada temporada tem. E com isso, vamos executar várias queries no banco de dados, e vamos aprender bastante sobre como otimizar, como diminuir o número de queries executadas.

Também vamos ver como adicionar esse tipo de mensagem, utilizando detalhes de sessão e flash messages. Vamos falar sobre detalhes como agrupamento de controllers, rotas nomeadas e muito mais.

E vamos ver outras formas de buscar dados da requisição, como o Laravel pode nos ajudar bastante, e mais para frente, começamos a falar sobre relacionamentos, inclusive como fazemos para uma série ter suas temporadas, e cada uma dessas temporadas ter seus episódios, por exemplo.

E também, em determinado momento, vamos ter que mexer um pouco com banco. Por exemplo, quando eu remover essa série teste, eu quero garantir que todas as temporadas e episódios também sejam removidos. Então isso vai ser cuidado, vamos recriar o banco com esses detalhes.

E além disso tudo, vamos ter também validação. Por exemplo, se eu tentar criar uma série sem nenhum nome, vamos ter uma mensagem de erro, "O campo nome é obrigatório". Se esse nome for muito pequeno, vamos ter uma outra mensagem de erro, "O campo nome precisa ter pelo menos 2 caracteres". Então vamos bater um papo sobre validações no Laravel também, e no final vamos ter essa aplicação.

Se você tiver reparado, eu tenho agora um debug bar. Isso é um componente externo, ele não faz parte do Laravel em si, mas ele pode nos ajudar bastante, principalmente nas tarefas que vamos fazer de otimização.

Mas eu já falei bastante, então se em qualquer momento desse treinamento você tiver alguma dúvida, não hesite, você pode abrir um tópico no nosso fórum, eu tento responder pessoalmente sempre que possível, mas quando eu não consigo, temos uma vasta comunidade de alunos, moderadores, instrutores e instrutoras, e com certeza alguém vai conseguir te ajudar.

Um último detalhe antes de colocarmos a mão na massa, é que não vamos ver tudo que tem para ver de Laravel nesse treinamento, até porque isso seria impossível. Então, essa é mais uma parte da nossa jornada estudando Laravel. Então espero que você aproveite bastante, e agora sim, te espero no próximo vídeo para começarmos o nosso estudo e aprendermos cada vez mais sobre Laravel.

Usando o framework - Criando séries

Bem-vindos de volta. Então, vamos começar a aprender alguns detalhes do framework. Nesse vídeo vamos atingir o mesmo resultado que temos até agora, de inserir uma série, por exemplo, mas com um código um pouco mais sucinto. Então vamos dar uma olhada no código.

Eu estou buscando um input que vem no corpo da minha requisição, preenchendo os dados de uma série e salvando no banco. Em um “Para saber mais” do primeiro treinamento, eu comentei que existem várias formas de eu pegar alguma coisa que vem do request. Então, isso não é diferente no caso de pegar um input do corpo da requisição. Além de utilizar o próprio método input, posso acessar diretamente a propriedade.

Então, se existe um campo “Nome”, que está vindo no corpo da minha requisição, eu posso acessar diretamente a propriedade “Nome” do meu request. E por trás, o Laravel já consegue buscar esse dado da requisição, utilizando os métodos mágicos, que já vimos em treinamentos anteriores, aquele __get.

Mas continuando, dessa forma eu tenho exatamente o mesmo resultado, estou pegando um campo “Nome”, que vem no corpo da requisição, para poder inserir essa série. E caso esse campo não exista no corpo da requisição, o Laravel vai tentar buscar em um parâmetro da rota. Mas podemos falar sobre parâmetros de rota mais para frente.

Agora, vamos lá, como estou falando sobre formas de buscar dados da requisição, vamos ver um outro formato interessante também. Eu vou fazer um dd(), que é um dump and die, que é um var_dump bonito e encerra a execução, ou seja, essa parte do código não continua executando.

E eu vou buscar do meu request todos os dados, então eu tenho um método chamado all, ele busca tudo que vem da requisição. Então, quando eu adicionar no navegador uma série chamada “Teste”, ele nos exibe o campo “nome” com o seu valor teste. Além disso, também vem o nosso token que adicionamos para a proteção de CSRF.

Então, com isso, eu consigo pegar um array associativo com todos os dados da requisição. Imagina que na série, além do nome, eu também tivesse uma sinopse, uma descrição, alguma coisa assim. Então, dessa forma, eu posso pegar todos os dados de uma vez, para adicionar na série.

Inclusive, falando em adicionar vários campos ao mesmo tempo, se eu tivesse vários campos, eu precisaria ter o nome, a descrição, atores e todos os campos que eu tivesse.

Só que o eloquent, que é o ORM do Laravel, já fornece uma forma de termos o que é chamado de mass assignment, ou atribuição em massa. Ou seja, preencher vários campos ao mesmo tempo. E isso podemos fazer através de Serie::create():. Então toda model do eloquent possui esse método estático chamado create. E ele recebe por parâmetro um array associativo com todas as propriedades que eu quero armazenar, com todas as colunas de banco de dados que eu quero armazenar.

Então, no caso, por exemplo, eu poderia passar Serie::crete:([‘nome’ => ‘Teste’]):. Isso já vai inserir no banco de dados uma nova série com o nome “Teste”.

Então, repara que eu tenho um array associativo vindo meu formulário, e eu posso passar diretamente esse array [‘nome’ => ‘Teste’] para o meu método create. Então eu vou copiar o request e atribuir em Serie::create, que ficaria Serie::create($request->all());, e vou remover o meu dd().

O que vai acontecer? Teoricamente, ele vai criar essa série com o nome que informei, e se para frente eu adicionasse um outro campo, ele também já enviaria para a série. Mas, teoricamente, porque se eu tentar executar isso, vamos ter um erro.

Então, repara que esse erro não é tão descritivo de cara, quando não conhecemos algumas técnicas, mas vamos dar uma lida nele. “Adicione o token à propriedade fillable para permitir o mass assignment”. Já falamos o que é o mass assignment, que é basicamente a sintaxe de passar várias informações de uma vez só para alguma model, ($request->all()), no caso, a model de série.

Só que ele está dizendo que eu preciso adicionar esse token. Só que eu não quero informar o token, só um nome. Então, isso é exatamente o propósito dessa propriedade fillable. Imagina que ao invés de série, eu esteja criando um usuário ou algo do tipo. A pessoa que mandou os dados do formulário, pode enviar um campo chamado “admin”, com valor marcado, com valor 1, alguma coisa assim.

Então, como estou pegando tudo que vem do usuário, eu estou fazendo alterações que eu não queria, eu queria, por exemplo, só alterar o e-mail desse meu usuário, ou criar um novo usuário só com nome e e-mail, sem esses dados de “admin”. Então, por isso ser perigoso, o Laravel obriga que informemos um detalhe.

Sempre que eu for utilizar mass assignment, preciso informar na minha “model”, quais campos podem ser atribuídos dessa forma. Então, eu posso utilizar a propriedade fillable para isso, protected $fillable.

Repara que é uma propriedade protected, protegida, e o valor dela é um array. Então eu preciso informar nesse array quais campos permito fazer essa atribuição em massa, esse mass assignment. No caso vai ser somente nome. E se amanhã ou depois eu tiver uma sinopse, eu adiciono a sinopse, simples assim, protected $fillable = [‘nome’, ‘sinopse’], então, eu não preciso mais alterar a forma como eu pego os dados do formulário. Isso simplifica bastante.

Então, agora vamos ver o que acontece. Porque eu estou passando um token, mas em série estou informando que eu só aceito o nome.

Como ele exibiu um erro, ele mostrou uma outra rota. Então vamos acessar de novo o navegador e em "nome" da série tentar o “Teste”, e selecionar o botão "adicionar". E repara que agora ele funcionou.

Quando eu tenho a propriedade fillable, ele simplesmente ignora tudo que não está nela. Então, eu estou passando um token, mas como ela não está na propriedade fillable, ele simplesmente ignora esse token, não tenta adicionar na série. Com isso, temos o mesmo resultado de inserção de série, mas com um código bem mais enxuto.

E agora, só para voltarmos naqueles detalhes do framework, se eu quisesse, por exemplo, pegar somente o nome, ou se eu tivesse mais campos, somente o nome e a descrição, por exemplo, eu posso utilizar o only. Então isso vai buscar somente os campos da requisição que eu adicionar.

Por exemplo, nome, no caso, e depois eu poderia adicionar sinopse, descrição. Mas se eu quiser o inverso, por exemplo, pegar todos os dados que vêm da requisição, com exceção do token, por exemplo, eu posso utilizar o except. Então eu vou passar Serie::create($request->except([‘_token’]));. Com isso, vou buscar tudo, com exceção do token.

Então, eu consigo brincar filtrando as informações que eu vou buscar ou buscando somente algumas específicas. Mas como eu já tenho o fillable, eu vou deixar no all sem problema. Então já começamos a brincar um pouco, conhecer mais detalhes do framework. E falando em detalhes, vou abrir as rotas em "routes > web.php".

E repara que eu tenho algumas rotas para o mesmo controller. Então, eu tenho que repetir o nome da classe o tempo todo, SeriesController:class. E existe uma forma de também simplificarmos essa parte. Vamos falar exatamente sobre isso no próximo vídeo.

Usando o framework - Agrupando actions

Bem-vindos de volta. Então já entendemos como simplificar um pouco o controller, vamos simplificar um pouco também as rotas.

Primeiro, a primeira coisa que eu quero fazer, é ao invés de quando eu acessar o nosso sistema, ele exibir aquela tela de mensagem inicial do Laravel, quero simplesmente redirecionar para a "/series", então return redirect(to: ‘/series’).

Então, quando acessar a página inicial no navegador, ele redireciona para as séries. Agora, além disso, como eu falei, eu quero agrupar essas rotas de alguma forma.

Existem duas formas de agrupar. Uma, que já existe há algum tempo e já citamos, só que primeiro eu vou te mostrar uma forma que é nova na Laravel 9. Então, vamos dar uma olhada nela.

Se eu tenho vários controllers executando ações diferentes, eu posso ter um Route:controller(). E que eu vou informar qual é o meu controller, qual vai estar controlando esse grupo de rotas que eu vou adicionar. E como eu vou adicionar um grupo de rotas, eu utilizo o método group, então Route::controller(controller:SeriesController::class)->group(function () {). Então dentro eu passo uma função anônima, e nessa função anônima posso ter todas as definições de rotas.

Então, dentro eu vou ter todas essas definições de rotas, mas você deve estar pensando que não simplificou nada, eu só compliquei. Então, como eu estou tendo um grupo de rotas desse controller, eu não preciso mais informar a classe. Então eu posso apagar [SerieController::class,, [SeriesController::class, e [SeriesController::class,, e só estou utilizando PhP Storm para já excluir de vários lugares ao mesmo tempo.

Então, repara que agora o controller não precisa mais ser especificado em cada uma das rotas, específico somente qual é o método utilizado, porque ele já vai buscar desse controller. Então, isso simplifica um pouco, ajuda um pouco nas nossas definições de rota. Então, quando eu atualizo no navegador, continua funcionando, a rota de adicionar também continua funcionando.

Agora, eu comentei que existe uma outra forma, e que já vimos, inclusive. Então vamos dar uma olhada na documentação do Laravel neste link. Em “Controllers”, temos resource controllers. E falamos sobre esse padrão de nomenclatura.

Então, se o meu controller e as minhas rotas seguem esse padrão, posso utilizar uma forma ainda mais simples de definir isso tudo, somente com Route::resource(name: ‘/series’, SerieController::class);. Vamos voltar para a documentação.

Na tabela "Actions Handle By Resource Controller", uma rota no verbo get para /series, que foi o que configuramos, vai executar o método index. Uma rota /series/create, vai executar o nosso método create. E assim por diante. Só que não estamos utilizando essas URLs da documentação, estamos utilizando “criar” ao invés de create.

Na hora de salvar, ao invés de ser somente “séries”, estamos mandando para /series/salvar, então isso não funcionaria com as nossas URLs hoje. Mas só para você ver como isso funcionaria, vamos para o navegador, a minha rota inicial vai funcionar, e se eu acessar "/series/create", vai funcionar também, ele vai acessar o método create.

Mas o nosso “criar”, ele não vai mais funcionar, porque ele vai tentar encontrar um método show, que é outra coisa, enfim, ele não vai funcionar dessa forma.

Então, eu não vou utilizar esse resource, simplesmente para eu continuar utilizando minhas URLs em português. Mas se você quiser, basta trocar para create e /series, que passamos a utilizar aquele padrão. E claro, precisamos alterar as URLs, os links, que no caso é um só, o link de adicionar.

Então, com isso aprendemos formas de agrupar nossos controllers, e falando em alterar a URL, imagina que seja frequente esse detalhe de alterar uma rota. Claro que existem questões de SEO, que eu preciso fazer os redirecionamentos, mas falando especificamente do código, se eu alterar para create, eu preciso ir na minha view de “series > index”.

E ao invés de criar, mudar para create. Então, seria interessante se pudesse informar que eu quero nesse link a minha rota que manda para esse método do controller. Qual é a URL em si, não me importa, isso pode mudar, mas eu quero de algum jeito identificar isso. E podemos fazer isso, e vamos aprender isso no próximo vídeo.

Sobre o curso Laravel: validando formulários, usando sessões e definindo relacionamentos

O curso Laravel: validando formulários, usando sessões e definindo relacionamentos possui 135 minutos de vídeos, em um total de 50 atividades. Gostou? Conheça nossos outros cursos de PHP em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda PHP acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas