Search code examples
laravellaravel-seeding

Laravel 8: How to seed a pivot table in many to many relationship


I want to seed my tables via seeder/factory. I want to seed a Pivot table, which connects the tables atg and debtor and is called atg_debtor, which hast an id, created_at, updated_at, atg_id, debtor_id.

When inserting data via Eloquent everything works fine. When I try to seed my db with Seeders/Factory it always tries to insert data to my atg table, which I don´t want. I want to seed the debtor table (that works fine) and the pivot table with a given atg_id and the dynamic debtor_id, which is created whilst seeding the debtor.

My Debtor Model:

<?php

namespace App\Models;

use App\Models\Atg;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Debtor extends Model
{
    use HasFactory;

    public function atg()
    {
        return $this->belongsToMany(Atg::class)->withTimestamps();
    }
}

The DebtorSeeder:

<?php

namespace Database\Seeders;

use App\Models\Atg;
use App\Models\Debtor;
use Illuminate\Database\Seeder;

class DebtorSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $debitor = Debtor::factory()
                ->count(1)
                ->hasAtg(1)
                ->create();
    }
}

The DebtorFactory:

<?php

namespace Database\Factories;

use App\Models\Debtor;
use Illuminate\Database\Eloquent\Factories\Factory;

class DebtorFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Debtor::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'created_at' => now(),
            'created_by_id' => '3',
            'rechtsform' => 'Unternehmen',
            'name' => $this->faker->company    
        ];
    }
}

Thank you!


Solution

  • so first you can check if in the database there is Atg, if no you can seed like you do, otherwise you can seed Debtor then save Atg in relations(->atg() is your relation name so improve it if i wrote wrong name) like so:

    P.S. Also i removed ->count(1) from Debtor because by default it creates one item.

    <?php
    
    namespace Database\Seeders;
    
    use App\Models\Atg;
    use App\Models\Debtor;
    use Illuminate\Database\Seeder;
    
    class DebtorSeeder extends Seeder
    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run()
        {
            $atg = Atg::first();
            if($atg){
               $debitor = Debtor::factory()
                    ->create();
    
               $debitor->atg()->save($atg);
            }else {
               $debitor = Debtor::factory()
                    ->hasAtg(1)
                    ->create();
            }
        }
    }