Laravel 使用递归 table 的播种器循环无法在每次递增后看到插入的数据

Laravel seeder loop with recursive table is unable to see inserted data after every increment

我正在创建一个 Laravel 工厂来创建产品模型,然后使用种子文件创建 100 个产品工厂。产品模型有一个自引用列,我知道如果数据库中没有产品模型,则该列应该为空。但之后我想获取一个随机产品 ID 并将其放入列中。我正在检查产品型号计数,如果它大于 0,我可以随机获取一个产品,否则只需将该列设置为空。但是在播种机循环中,每个查询都是 returning 0 列,我不知道为什么。

这就是我想在工厂里做的事情。

<?php

use Faker\Generator as Faker;
use Illuminate\Support\Facades\Log;

$factory->define(App\Product::class, function (Faker $faker) {
    // Logging count to see if it's changing.
    Log::debug(App\Product::count());

    // For the first insert I know there are no products
    // so I want to set the first row to null.
    $product = null;
    // While on the second row the count should be 1
    // but it's returning 0 every time in the seeder loop
    if (App\Product::count() < 0) {
        $product = App\Product::all()->random()->id;
    }

    return [
        'model' => $faker->word,
        'monitor_setup_price' => $faker->optional()->randomFloat(2, 0, 1000),
        'monitor_monthly_price' => $faker->optional()->randomFloat(2, 0, 1000),
        'manage_setup_price' => $faker->optional()->randomFloat(2, 0, 1000),
        'manage_monthly_price' => $faker->optional()->randomFloat(2, 0, 1000),
        'maximize_setup_price' => $faker->optional()->randomFloat(2, 0, 1000),
        'maximize_monthly_price' => $faker->optional()->randomFloat(2, 0, 1000),
        'decommissioned' => 0,
        'category_id' => factory(App\Category::class)->create(),
        'vendor_id' => factory(App\Vendor::class)->create(),
        'type_id' => factory(App\Type::class)->create(),
        'product_id' => $product,
        'created_by' => App\User::all()->random()->id,
        'updated_by' => App\User::all()->random()->id,
        'created_at' => $faker->dateTimeBetween('-2 years', '-1 month'),
        'updated_at' => $faker->dateTimeThisMonth()
    ];
});

播种机只是 运行工厂 100 次。

<?php

use Illuminate\Database\Seeder;

class ProductsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Product::class, 100)->create();
    }
}

我的解决方案是在播种机中手动 运行 一个 for 循环。这对我来说不是那么干净,我也想确切地知道为什么代码会这样工作。

旁注:我的问题与此类似 [Seed a recursive table using factories in Laravel] 除了此处的解决方案不起作用。

带有递归 table 的播种器循环无法在每次递增后看到插入的数据。为什么每次循环后计数都是return0?

我猜这是因为工厂首先多次为给定的模型创建一个构建器,然后创建模型集合并将它们保存到数据库中,所以即使您在每次迭代中都获得了所有产品, 其中任何一个都已经持久化到数据库中了。

也许你可以这样做

$factory->define(App\Product::class, function (Faker $faker) use (&$id) {
    return [
        // ...
        'product_id' => rand(1, $id++),
        // ...
    ];
});

您可能还想看看

https://github.com/laravel/framework/blob/5.7/src/Illuminate/Foundation/helpers.php#L493

https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Eloquent/Factory.php#L255

https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Eloquent/FactoryBuilder.php

看到整个事情的细节。