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] 除了此处的解决方案不起作用。
- Laravel 5.7
- PHP 7.3.1
带有递归 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
看到整个事情的细节。
我正在创建一个 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] 除了此处的解决方案不起作用。
- Laravel 5.7
- PHP 7.3.1
带有递归 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
看到整个事情的细节。