Laravel seed создает неправильное количество строк в БД - PullRequest
2 голосов
/ 02 марта 2020

Я пытаюсь создать сеялку со связями

public function run()
{
    factory(Company::class, 10)->create()->each(function ($company){
        $company->buildings()->saveMany(factory(Building::class, 5)->create()->each(function ($building){
            $building->facilities()->saveMany(factory(App\Models\Facility::class,5)->make());
        }));
    });
}

Этот код должен создать 10 компаний и 5 зданий для каждой компании и 5 объектов для каждого здания. компании 10 зданий 50 объектов 250

но я получаю

компании 300 зданий 310 объектов 250, что не имеет смысла

мои заводы:

$factory->define(Company::class, function (Faker $faker) {
    $name = $faker->lastName;
    $company = $name.' Company';
    return [
        'name' => $company,
        'shortName' => $name
    ];
});
$factory->define(Building::class, function (Faker $faker) {
    return [
        'name' => 'Hotel '.$faker->lastName,
        'company_id' => function () {
            return factory(App\Models\Company::class)->create()->id;
        }
    ];
});
$factory->define(Facility::class, function (Faker $faker) {
    $elements = array('lavabo','ducha');

    return [
        'name' => $faker->randomElement($elements).' '.$faker->numerify('Habitacion ###'),
        'building_id' => function () {
            return factory(App\Models\Building::class)->create()->id;
        }
    ];
});

И база данных отправителя. php

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UserSeeder::class);
        $this->call(CompaniesSeeder::class);
    }
}

1 Ответ

1 голос
/ 02 марта 2020

Решение

Проблема возникает отсюда:

$company->buildings()->saveMany(factory(Building::class, 5)->create()->each(function ($building){
    $building->facilities()->saveMany(factory(App\Models\Facility::class,5)->make());
}));

Каждый раз, когда вы создаете новое здание и объект, оно также создает новую компанию на вашем заводе.

Просто передайте соответствующие параметры вашей функции create, чтобы Faker знал, что не следует создавать новую компанию и здание.

Измените:

factory(Building::class, 5)->create()

На:

factory(Building::class, 5)->create(['company_id' => $company->id]);

И примените те же логики c для Facility.

factory(App\Models\Facility::class,5)->make(['building_id' => $building->id])

Примечание:

Вы также можете упростить свои фабрики, заменив функцию обратного вызова следующим образом:

$factory->define(Building::class, function (Faker $faker) {
    return [
        'name' => 'Hotel '.$faker->lastName,
        'company_id' => factory(Company::class),
    ];
});
...