The Blog

Laravel: Criando os relacionamentos das tabelas – Reiniciando


Já criamos os arquivos de Migrations e também criamos as rotas, models e controllers do nosso sistema financeiro. Agora nós vamos identificar os relacionamentos nos arquivos pertinentes.

Abaixo eu descrevo a lista de tabelas e seus relacionamentos do nosso banco de dados:

  • Knowledge
  • Plans
  • Roles
  • Parameters
    • plans_id => Plans
  • Users
  • Users_Parameters (Tabela de relacionamento)
    • users_id => Users
    • parameters_id => Parameters
    • roles_id => Roles
  • Account_Plans
    • parameters_id => Parameters
    • plangroup => Account_Plans
  • Costs
    • parameters_id => Parameters
  • Document_Types
    • parameters_id => Parameters
  • Event_Types
    • parameters_id => Parameters
  • Banks
    • parameters_id => Parameters
  • Boxes
    • parameters_id => Parameters
  • Cards
    • parameters_id => Parameters
  • Customers
    • parameters_id => Parameters
  • Providers
    • parameters_id => Parameters
  • Plannings
    • parameters_id => Parameters
    • costs_id => Costs
    • providers_id => Providers
    • customers_id => Customers
    • account_plans_id => AccountPlans
  • Transfers
    • parameters_id => Parameters
    • banks_id => Banks
    • boxes_id => Boxes
    • costs_id => Costs
    • event_types_id => Event_Types
    • document_types_id => Document_Types
    • account_plans_id => Account_Plans
    • banks_dest => Banks
    • boxes_dest => Boxes
    • costs_dest => Costs
    • account_plans_dest => Account_Plans
  • Movements
    • parameters_id => Parameters
    • banks_id => Banks
    • boxes_id => Boxes
    • cards_id => Cards
    • plannings_id => Plannings
    • costs_id => Costs
    • event_types_id => Event_Types
    • document_types_id => Document_Types
    • providers_id => Providers
    • customers_id => Customers
    • account_plans_id => Account_Plans
  • Movement_Checks
    • parameters_id => Parameters
    • banks_id => Banks
    • boxes_id => Boxes
    • costs_id => Costs
    • event_types_id => Event_Types
    • providers_id => Providers
    • customers_id => Customers
    • account_plans_id => Account_Plans
    • transfers_id => Transfers
    • movements_id => Movements
  • Movement_Banks
    • parameters_id => Parameters
    • banks_id => Banks
    • costs_id => Costs
    • event_types_id => Event_Types
    • document_types_id => Document_Types
    • providers_id => Providers
    • customers_id => Customers
    • account_plans_id => Account_Plans
    • transfers_id => Transfers
    • movements_id => Movements
    • movement_checks_id => Movement_Checks
  • Movement_Boxes
    • parameters_id => Parameters
    • boxes_id => Boxes
    • costs_id => Cards
    • event_types_id => Event_Types
    • providers_id => Providers
    • customers_id => Customers
    • account_plans_id => Account_Plans
    • transfers_id => Transfers
    • movements_id => Movements
    • movement_checks_id => Movement_Checks
  • Movement_Cards
    • parameters_id => Parameters
    • banks_id => Banks
    • boxes_id => Boxes
    • cards_id => Cards
    • costs_id => Costs
    • event_types_id => Event_Types
    • providers_id => Providers
    • customers_id => Customers
    • document_types_id => Document_Types
    • account_plans_id => Account_Plans
    • movements_id => Movements
  • Movements_Movement_Cards (Tabela de relacionamento)
    • parameters_id => Parameters
    • movements_id => Movements
    • cards_id => Cards
  • Movement_Mergeds (Tabela de relacionamento)
    • parameters_id => Parameters
    • movements_id => Movements
    • movements_merged => Movements
  • Movement_Recurrents (Tabela de relacionamento)
    • parameters_id => Parameters
    • movements_id => Movements
    • movement_cards_id => Movement_Cards
  • Balances
    • parameters_id => Parameters
    • banks_id => Banks
    • boxes_id => Boxes
    • cards_id => Cards
    • plannings_id => Plannings
  • Regs
    • parameters_id => Parameters
    • users_id => Users

Vamos alterar o arquivo Model de Plans e criar o relacionamento com a tabela Parameters. Abra o arquivo ‘app/Plan.php’ e deixe-o como no exemplo abaixo:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Plan extends Model
{
    protected $table = 'plans';
    
    public function parameter()
    {
	return $this->hasOne(Plan::class, foreignKey: 'plans_id', localKey: 'id');
    }
}

Para exibir os dados da consulta, o arquivo Controller em ‘app/Http/Controllers/PlanController.php’ deverá conter as seguintes linhas:

<?php

namespace App\Http\Controllers;

use App\Parameter;
use Illuminate\Http\Request;

class PlanController extends Controller
{
    ...
    public function show($id)
    {
	//Consulta o dado pelo ID
        $plan = Plan::where('id', $id)->first();
        
        if (!empty($plan)) {
	        
	        //Consulta os perfis que utilizam o plano
	        $parameters = $plan->parameter()->get();
	        
	        if (!empty($parameters)) {
		        
		        //Envie para a View os dados da consulta
		        
	        }//if (!empty($parameters))
	        
        }//if (!empty($plan))
    }
    ...
}

Agora vamos realizar a pesquisa reversa. Abra o Model de Parameters em ‘app\Parameter.php’ e escreva as seguintes linhas:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Parameter extends Model
{
    protected $table = 'parameters';
    
    public function plan()
    {
	    $this->belongsTo(Plan::class, ForeignKey: 'plans_id', ownerKey: 'id');
    }
}

No Controller de Parameters em ‘app/Http/Controllers/ParameterController.php’, é possível listar o plano do perfil. É necessário que ele se pareça com o exemplo abaixo:

<?php

namespace App\Http\Controllers;

use App\Parameter;
use Illuminate\Http\Request;

class ParameterController extends Controller
{
    ...
    public function show($id)
    {
	//Consulta o dado pelo ID
        $parameter = Parameter::where('id', $id)->first();
        
        if (!empty($parameter)) {
	        
	        //Consulta o plano do perfil atual
	        $plan = $parameter->plan()->first();
	        
	        if (!empty($plan)) {
		        
		        //Envie para a View os dados da consulta
		        
	        }//if (!empty($plan))
	        
        }//if (!empty($parameter))
    }
    ...
}

RESUMO

Então, agora vamos resumir o que foi feito para facilitar a compreensão.

Model Principal
(aquele que teve seu id referenciado como foreign key)

public function nome_da_tabela_referenciadora()
{
    return $this->hasOne(Plan::class, foreignKey: 'foreignKey_id', localKey: 'id');
}

Controller Principal
(aquele que teve seu id referenciado como foreign key)

public function show($id)
{
    //Consulta os dados da tabela atual
    $tabela_atual = Tabela_atual::where('id', $id)->first();

    //Consulta os dados na tabela referenciadora
    $resultado_da_tabela_referenciadora = $tabela_atual->nome_da_tabela_referenciadora()->first();

    //Exibe os dados na tela
    dd($resultado_da_tabela_referenciadora);
}

Model Referenciador
(aquele que possui a foreign key apontando para a tabela principal)

public function nome_da_tabela_principal()
{
    $this->belongsTo(Plan::class, ForeignKey: 'foreignKey_id', ownerKey: 'id');
}

Controller Referenciador
(aquele que possui a foreign key apontando para a tabela principal)

public function show($id)
{
    //Consulta os dados da tabela atual
    $tabela_atual = Tabela_atual::where('id', $id)->first();

    //Consulta os dados da tabela principal
    $resultado_da_tabela_principal = $tabela_atual->nome_da_tabela_principal()->first();

    //Exibe os dados na tela
    dd($resultado_da_tabela_principal);
}

O que muda entre os relacionamentos 1:1, 1:N e N:N?

1:1 Model

$this->hasOne(Tabela_relacionada::class, foreignKey: 'chave_estrangeira_id', localKey: 'id');

1:1 Controller

$tabela_atual->tabela_relacionada()->first();

1:N Model

$this->hasMany(Tabela_relacionada::class, ForeignKey: 'chave_estrangeira_id', localKey: 'id');

1:N Controller

$tabela_atual->tabela_relacionada()->get(); 
//Use um laço de repetição para ler o retorno

Model de retorno para 1:1 e 1:N:

$this->belongsTo(Tabela_relacionada::class, ForeignKey: 'chave_estrangeira_id', ownerKey: 'id');

N:N Model

$this->belongsToMany(Tabela_relacionada::class, Table: 'tabela_de_relacionamentos', ForeignPivotKey: 'tabela_atual_id', relatedPivotKey: 'tabela_relacionada_id');

N:N Controller

$tabela_atual->tabela_relacionada()->get(); 
//Use um laço de repetição para ler o retorno

As regras acima foram aplicadas nos arquivos do nosso projeto. A documentação completa está em https://laravel.com/docs/7.x/eloquent-relationships.

Esse projeto possui todo o código disponível em https://github.com/Maksoud/reiniciando e o projeto está hospedado em https://reiniciando.maksoud.dev/. Deixe seu comentário abaixo e colabore com esse projeto.

Leave a comment