PHP

24 jun, 2020

3 Tipos de Relacionamento entre Tabelas no Laravel

Publicidade

Olá caro leitor, estou de volta com mais um artigo, dessa vez iremos entender todas as formas de relacionamento entre tabelas existentes no Laravel, e para isso vamos usar o projeto que iniciamos no artigo anterior, então se você ainda não viu, corre lá!

Considerando que você já abriu o projeto no seu editor de código, e já está com o banco de dados ligado e configurado na aplicação, chegou a hora de implementarmos nossas relações entre tabelas.

  • 1 – Relação One to One (Um para Um)

Esse é o tipo de relação mais simples que existe. Consiste em uma relação de uma determinada tabela com outra, por exemplo, um usuário (tabela users) precisa informar o seu endereço quando for realizar o cadastro, e no lugar de criar vários campos na tabela users, é criada uma nova tabela de endereços (addresses) para armazenar essas informações. Dessa forma evitamos que a tabela de usuários fique com campos de mais, e podemos usar a tabela addresses para armazenar os dados de um endereço que não seja, necessariamente, de um usuário, podendo ser de um cliente ou um fornecedor, por exemplo.

Por padrão o Laravel já possui a migração responsável para criar a tabela de usuários, então precisamos apenas criar nossa migração para a tabela de endereços. No seu terminal, na raiz do projeto, digite o seguinte comando:

php artisan make:model Address -m

Esse comando irá criar a model e a respectiva migration, tudo de uma vez.

Agora em database/migrations encontre a o arquivo da migração que acabamos de criar e deixe a função up() igual a minha:

E execute o seguinte comando no seu terminal:

php artisan migrate

Tabela criada com sucesso

Antes de testarmos a relação precisamos configurar a Model Address. Em app/ encontre o arquivo Address.php e o deixe igual ao meu:

Com a model do endereço devidamente configurada, agora podemos configurar a nossa relação entre Usuários e Endereços.

Ainda em app/, encontre o arquivo User.php, e inclua a seguinte função:

Esse é o padrão do Laravel para declarar um relacionamento One to One, basta retornar o método hasOne(), informando como primeiro argumento a Model que o referencia, e no segundo argumento qual é o campo, na outra Model, que armazena a chave estrangeira.

Dessa forma estamos literalmente dizendo: Laravel, eu, usuário, tenho um endereço, que está armazenado na model Address (tabela addresses), e eu sei disso porque o campo id_usuario está me referenciando.

Chegou a hora de testarmos a nossa relação! No seu terminal, execute:

php artisan tinker

O Tinker é um console interativo do Laravel, um shell do PHP com acesso às classes do nosso projeto! Com o tinker conseguimos criar registros no banco de dados, e é exatamente isso que vamos fazer.

Primeiro de tudo, vamos criar o nosso usuário:

Pronto, criamos o nosso usuário, e ele possui o id 1. Agora vamos criar o nosso endereço, referenciando este usuário:

Para testar se a relação que declaramos está funcionando, faremos a seguinte busca no banco:

Estamos buscando o usuário de id 1, porém estamos usando o método with(), que complementa a query para buscar e trazer também as relações, e nesse caso estamos trazendo o endereco, que foi o nome que escolhemos para a função de relação que declaramos na model User.

Perceba que ele trouxe o usuário e também trouxe as informações!

Se fizermos a mesma busca, só que dessa vez colocando em uma variável, conseguimos acessar facilmente as propriedades de nossa relação, veja:

Para obter, por exemplo, o logradouro:

 

  • 2 – One to Many (Um para Vários)

 

A relação de um para vários funciona da mesma forma que a anterior, um para um, na hora da criação da tabela, a diferença está na declaração da relação na model.

Vamos usar a mesma tabela de endereços para exemplificar esse caso! Precisamos alterar apenas a declaração da relação. Em app/ encontre o arquivo User.php e altere a função endereco() para que fique como a minha:

Perceba que não usamos mais hasOne() e sim hasMany(). E além disso o nome da função está no plural.

Dessa forma estamos literalmente dizendo: Laravel, eu, usuário, tenho vários endereços, que estão armazenados na model Address (tabela addresses), e eu sei disso porque o campo id_usuario está me referenciando.

Feito isso, vamos executar os mesmos testes utilizando o tinker. Primeiro, vamos criar mais um endereço, referenciando o usuário que criamos, que no meu caso possui o id 1:

E faremos a busca, utilizando o with():

Pronto, conseguimos obter facilmente nossos dois endereços, só que para acessar as propriedades não podemos simplesmente fazer como no exemplo do tópico 1, temos que informar a posição do array:

A nossa relação de um para muitos está configurada.

 

  • 3 – Many to Many (Vários para Vários)

 

Esse tipo de relação é um pouco mais complexa do que as duas anteriores, porém pode ser facilmente entendida e principalmente executada, com a ajuda do Laravel.

Vamos continuar usando a tabela de usuários como exemplo, só que dessa vez vamos trabalhar com regras de acesso ao invés de endereços. É muito comum sistemas possuírem divisões de permissão de acesso para os usuários, alguns podem acessar tudo enquanto outros podem acessar apenas o financeiro, ou o jurídico, e por aí vai…

Agora vamos ver como é feita essa ligação entre vários usuários e as várias regras existentes.

Vamos começar criando um novo usuário, ainda utilizando o tinker:

Agora temos dois usuários, de id 1 e 2, respectivamente. Digite exit no seu terminal tinker para finalizar, e vamos criar uma nova migração, desta vez para guardarmos as regras do sistema:

Em database/migrations encontre o arquivo da migração que acabamos de criar e deixe a função up() igual a minha:

E execute, no terminal:

php artisan migrate

A tabela foi criada:

Agora vamos configurar a nossa Model, em app/ encontre o arquivo Regra.php e o deixe como o meu:

O primeiro passo é criarmos algumas regras para servir de exemplo, para isso execute o tinker e crie 3 regras:

Perceba que desta vez não utilizamos o método create() e sim o insert(), que permite a criação de múltiplos registros de uma só vez.

Nossas regras foram criadas com sucesso, agora precisamos fazer a vinculação das regras com os usuários.

Neste caso, dois ou mais usuários podem ter a mesma regra de acesso, certo? Então usar uma chave estrangeira na própria tabela de regras não funcionaria. É aí que entra a relação vários para vários.

Precisamos criar uma tabela intermediária (pivot), que vai armazenar o id do usuário e também o id da regra!

No seu terminal, execute:

php artisan make:model RegraUser -m

Em database/migrations encontre o arquivo de migração que acabamos de criar e deixe a função up() igual a minha:

E agora execute:

php artisan migrate

Tabela criada com sucesso

Feito isso, vá em app/ e encontre o arquivo RegraUser.php, e o deixe igual ao meu:

Muito bem, temos dois usuários e três regras criadas em nosso banco de dados, chegou a hora de vincular isso. Vamos fazer o seguinte:

O Usuário de id 1 possui acesso de administrador, e o usuário de id 2 possui acesso ao financeiro e ao jurídico. Vamos fazer acontecer, abra o tinker para criamos esse vínculos na tabela de regra_users:

E por último, precisamos configurar na model User a função que vai obter as regras, em app/ encontre o arquivo User.php e adicione a função abaixo:

Perceba que a declaração deste tipo de relacionamento é diferente, usamos um outro método, o belongsToMany() e informamos quatro argumentos, em sequência:

  1. A Model que queremos alcançar através da tabela pivot
  2. O nome da tabela pivot
  3. O campo que referencia a Model que estamos (no nosso caso estamos na User)
  4. O campo que referencia a Model que queremos alcançar (no nosso caso é a Regra)

Fazendo dessa forma nós encurtamos o caminho, sem precisar passar da users para a regra_users, e depois para a regras, pois o Laravel já está fazendo isso de forma oculta.

Chegou a hora de testar, abra o tinker no seu terminal e execute a seguinte busca:

Correto! O nosso usuário de id 1 possui apenas a regra de Administrador

E o usuário de id 2 possui regras de Financeiro e Jurídico!

Conclusão

Essas são as três formas mais básicas de configurar um relacionamento entre tabelas no Laravel, porém não são as únicas. Em uma outra oportunidade mostrarei as outras formas, mais avançadas, de configurar relacionamentos mais complexos.

Você pode experimentar muitas formas de relacionar as tabelas apenas com estes 3 tipos, instale um projeto do Laravel e comece a “brincar”, essa é a forma mais rápida de efetivamente aprender.