Como criar relacionamentos entre tabelas com hasMany no Laravel 10


Neste tutorial, será apresentado como criar relacionamentos entre tabelas com hasMany no Laravel 10.

Primeiramente, será mostrado como criar uma chave estrangeira com migration para estabelecer o relacionamento entre as tabelas.

Em seguida, será apresentado por que utilizar o InnoDB no banco de dados.

Por fim, será mostrado como recuperar registros em duas tabelas com Laravel 10.


Download do código fonte desenvolvido na aula: Download

Curso de Laravel: Mais Detalhes do Curso

Playlist completa sobre Laravel: Acessar

Receber as aulas gratuitas do curso de Laravel: Acessar


Para começar, é utilizado como base o projeto da aula "Como usar o SweetAlert para confirmar a exclusão do registro no Laravel 10".

Criado a migration "database/migrations/2024_01_25_084448_create_situacoes_contas_table.php" para criar a tabela "situacoes_contas".

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('situacoes_contas', function (Blueprint $table) {
            $table->id();
            $table->string('nome');
            $table->string('cor');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('situacoes_contas');
    }
};

Executado a migration.

php artisan migrate

Criada a model "app/Models/SituacaoConta.php", utilizando o hasMany para estabelecer o relacionamento um para muitos com a model "Conta".

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class SituacaoConta extends Model
{
    use HasFactory;

    // Indicar o nome da tabela
    protected $table = 'situacoes_contas';

    // Indicar quais colunas podem ser cadastrada
    protected $fillable = ['nome', 'cor'];

    public function conta()
    {
        return $this->hasMany(Conta::class);
    }
}

Na model "app/Models/Conta.php", criado o relacionamento com a model "SituacaoConta.php" utilizando "belongsTo".

public function situacaoConta()
{
    return $this->belongsTo(SituacaoConta::class);
}

Criada a model e o relacionamento entre as tabelas, é possível adicionar a coluna "situacao_conta_id" como chave estrangeira na tabela "contas". No entanto, o tipo das tabelas deve ser "InnoDB".

Para adicionar a coluna "situacao_conta_id", criada a migration "database/migrations/2024_01_25_084701_alter_contas_table.php".

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('contas', function (Blueprint $table) {
            $table->foreignId('situacao_conta_id')->default(2)->after('vencimento')->constrained('situacoes_contas');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::create('contas', function (Blueprint $table) {
            $table->dropColumn('situacao_conta_id');
        });
    }
};

O próximo passo é criar a seeder "database/seeders/SituacaoContaSeeder.php" para cadastrar dados na tabela "situacoes_contas".

<?php

namespace Database\Seeders;

use App\Models\SituacaoConta;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class SituacaoContaSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        if(!SituacaoConta::where('nome', 'Paga')->first()){
            SituacaoConta::create([
                'nome' => 'Paga',
                'cor' => 'success',
            ]);
        }
        if(!SituacaoConta::where('nome', 'Pendente')->first()){
            SituacaoConta::create([
                'nome' => 'Pendente',
                'cor' => 'danger',
            ]);
        }
        if(!SituacaoConta::where('nome', 'Cancelada')->first()){
            SituacaoConta::create([
                'nome' => 'Cancelada',
                'cor' => 'warning',
            ]);
        }
    }
}

Para recuperar dados de duas tabelas com o Laravel, na controller "app/Http/Controllers/ContaController.php", foi utilizado o "with".

->with('situacaoConta')

Após recuperar a situação da conta, na view "resources/views/contas/index.blade.php", acrescentado o cabeçalho na tabela.

<th scope="col">Situação</th>

Também foi impressa a situação com o badge do Bootstrap.

<td>{!! '<span class="badge text-bg-'. $conta->situacaoConta->cor .'">' . $conta->situacaoConta->nome . '</span>' !!}</td>

Em função de ter implementado corretamente o relacionamento na model, não é necessário utilizar o "with", conforme implementado na controller "app/Http/Controllers/ContaController.php".

Para mostrar como recuperar dados de duas tabelas sem o uso do "with", na view "resources/views/contas/show.blade.php", a situação é impressa diretamente.

<dt class="col-sm-3">Situação</dt>
<dd class="col-sm-9">{!! '<span class="badge text-bg-'. $conta->situacaoConta->cor .'">' . $conta->situacaoConta->nome . '</span>' !!}</dd>

Baixar o código-fonte completo do projeto.

Bom, era isso. Espero que o tutorial tenha sido útil!