Laravel 8:如何在多对多关系中播种枢轴 table

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

我想通过 seeder/factory 播种我的 table。 我想播种一个 Pivot table,它连接 tables atgdebtor 并称为 atg_debtor,它有一个 idcreated_at, updated_at, atg_id, debtor_id.

通过Eloquent插入数据时一切正常。当我尝试用 Seeders/Factory 为我的数据库播种时,它总是试图将数据插入我的 atg table,这是我不想要的。我想用给定的 atg_id 和动态的 debtor_id 播种 debtor table(效果很好)和枢轴 table,这是在播种时创建的债务人。

我的债务模型:

<?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();
    }
}

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();
    }
}

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    
        ];
    }
}

谢谢!

所以首先你可以检查数据库中是否有Atg,如果没有你可以像你一样播种,否则你可以播种Debtor然后保存Atg在关系中( ->atg() 是你的关系名称,如果我写错了,请改进它)像这样:

P.S。我还从 Debtor 中删除了 ->count(1),因为默认情况下它会创建一个项目。

<?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();
        }
    }
}

假设您单独为数据库表播种:

// Seed 50 Atg records
Atg::factory(50)->create();

// Seed 4 Debtor records
Debtor::factory(4)->create();

您可以覆盖 Debtor 工厂中的 configure 方法,以便在创建模型后附加一些 Atg 模型:

class DebtorFactory extends Factory
{
    public function configure()
    {
        return $this->afterCreating(function (Debtor $debtor) {
            // Once a Debtor record has been created
            // Pick between 1 and 5 Atg records in a random order
            // Associate the Atg and Debtor records
            $debtor->atg()
                   ->attach(Atg::inRandomOrder()->take(random_int(1, 5))->pluck('id'));
        });
    }
}

您可以使用 hasAttached 方法在 Laravel 8 中播种枢轴 table 在您的 DatabaseSeeder class 文件中。

Atg::factory()->hasAttached(
               Debtor::factory();
              )
              ->create();

这将帮助您每个 Atg 在 atg_debtor table 中创建具有动态债务人 ID 的项目。但它需要在模型 class 绑定中连接。

class Debtor extends Model
{
  use HasFactory;
    
   public function atg()
   {
      return $this->belongsToMany(Atg::class)->withTimestamps();
   }
 }

其他方法, 您可以使用 Using Magic Methods 在 Pivot 中创建种子数据 Table

Atg::factory()->hasDebtor(1)
              ->create();

参考方法如下 https://laravel.com/docs/8.x/database-testing#pivot-table-attributes