Laravel多态数据库Seeder工厂

Hyp*_*onX 3 polymorphic-associations laravel-5 laravel-seeding

如何为以下配置创建数据库种子工厂?

用户

// create_users_table.php
Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    ...
}

// User.php
public function notes()
{
    return $this->morphMany('App\Note', 'noteable');
}
Run Code Online (Sandbox Code Playgroud)

复杂

// create_complex_table.php
Schema::create('complex', function (Blueprint $table) {
    $table->increments('id');
    ...
}

// Complex.php
public function notes()
{
    return $this->morphMany('App\Note', 'noteable');
}
Run Code Online (Sandbox Code Playgroud)

笔记

// create_notes_table.php
Schema::create('notes', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('noteable_id');
    $table->string('noteable_type');
    ...
}

// Note.php
public function noteable()
{
    return $this->morphTo();
}
Run Code Online (Sandbox Code Playgroud)

我正在努力寻找最可靠的方法来确保我不只是填写id可能不存在的random 。

maa*_*auw 7

如果您使用变形贴图,则给定的解决方案将不起作用,因为类型与类名不同。

这将与变形贴图结合使用。

直到 Laravel 7

$factory->define(App\Note::class, function (Faker $faker) {
    $noteable = $faker->randomElement([
        App\User::class,
        App\Complex::class,
    ]);

    return [
        'noteable_id' => factory($noteable),
        'noteable_type' => array_search($noteable, Relation::$morphMap),
        ...
    ];
});
Run Code Online (Sandbox Code Playgroud)

来自 Laravel 8

public function definition(): array
{
    /** @var class-string<\App\Models\User|\App\Models\Complex> $noteable */
    $noteable = $this->faker->randomElement([
        App\Models\User::class,
        App\Models\Complex::class,
    ]);

    return [
        'noteable_type' => array_search($noteable, Relation::$morphMap),
        'noteable_id' => $noteable::factory(),
    ];
}
Run Code Online (Sandbox Code Playgroud)

有关变形贴图的更多信息可以在这里找到: https: //laravel.com/docs/8.x/eloquent-relationships#custom-polymorphic-types


Bar*_*uda 6

我改进了HyperionX的答案,并从中删除了静态元素。

$factory->define(App\Note::class, function (Faker $faker) {
    $noteable = [
        App\User::class,
        App\Complex::class,
    ]; // Add new noteables here as we make them
    $noteableType = $faker->randomElement($noteables);
    $noteable = factory($noteableType)->create();

    return [
        'noteable_type' => $noteableType,
        'noteable_id' => $noteable->id,
        ...
    ];
});
Run Code Online (Sandbox Code Playgroud)

基本上,我们随机选择一个值得注意的类,然后调用它自己的工厂来获得一个值得注意的实例,这样就摆脱了OP答案的静态性。


Hyp*_*onX 2

虽然比我想要的更静态,但这是我的解决方案:

我为每个类创建了 20 个模型,这样我就可以确保创建的 Notes 不会尝试链接到可能不存在的东西,从而留下一个悬空的 Note 对象。

// NotesFactory.php
$factory->define(App\Note::class, function (Faker $faker) {
    $noteable = [
        App\User::class,
        App\Complex::class,
    ];

    return [
        'noteable_id' => $faker->numberBetween(0,20),
        'noteable_type' => $faker->randomElement($noteable),
        ...
    ];
});
Run Code Online (Sandbox Code Playgroud)