Laravel Посев дает в 3 раза больше результатов, чем ожидалось - PullRequest
0 голосов
/ 13 апреля 2020

Я работаю над проектом Laravel и пытаюсь заполнить базу данных, используя фабрики моделей.

У меня есть таблица баннеров и связанная модель BannerTranslations для хранения переведенных значений. Проект будет иметь 3 языка. Я пытаюсь вставить 5 фиктивных значений в таблицу Banners, относящуюся к BannerTranslations. Теоретически я ожидаю 3 строки перевода, созданные для каждой строки Banner, что должно привести к 15 записям (3x5) в таблице BannerTranslations в конце. Но вместо этого я получаю 45 записей. Каждая строка перевода засевается 3 раза вместо 1. Я уверен, что упускаю что-то очень очевидное, но не могу понять, что.

миграция перевода:

public function up()
{
    Schema::create('banner_translations', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedInteger('banner_id');
        $table->string('locale')->index();

        $table->string('title');
        $table->string('spot')->nullable();
        $table->text('body')->nullable();
        $table->string('alt')->nullable();

        //$table->unique(['banner_id', 'locale']);
        $table->foreign('banner_id')->references('id')->on('banners')->onDelete('cascade');

        $table->timestamps();
    });
}

BannerTranslationsFactory :

use App\BannerTranslation;
use Faker\Generator as Faker;

$factory->define(BannerTranslation::class, function (Faker $faker) {
    return [
        'banner_id' => function (array $banner) {
            return App\Banner::find($banner['id'])->id;
        },
        'locale' => function (array $banner) {
            return App\BannerTranslation::find($banner['banner_id'])->locale;
        },
        'title' => $faker->sentence(2),
        'spot' => $faker->sentence(2),
        'body' => $faker->realText(rand(80, 200)),
        'alt' => null,
    ];
});

и BannersTableSeeder:

$banners = factory(App\Banner::class, 5)->create()->each(function ($banner) {

    $lang_count = count(config('laravellocalization.supportedLocales'));

    foreach(LaravelLocalization::getSupportedLanguagesKeys() as $i => $key) {
        factory(App\BannerTranslation::class, $lang_count)->create([
            'banner_id' => $banner->id,
            'locale' => $key,
        ]);
    }
});

В результате получается 3 одинаковых ключевых строки в каждом переводе ('en', 'en', 'en', 'de', 'de' , 'de', 'fr', 'fr', 'fr') вместо ('en', 'de', 'fr'). И из-за этого он возвращает уникальную ошибку contstraint.

1 Ответ

2 голосов
/ 13 апреля 2020

Я не очень хорошо знаком с использованием фабрик, но, глядя на вас и проверяя документы , ваша проблема со вторым параметром в factory(App\BannerTranslation::class, $lang_count). Вы уже просматриваете LaravelLocalization::getSupportedLanguagesKeys(), и для каждой вы создаете 3 записи.

Попробуйте:

$banners = factory(App\Banner::class, 5)->create()->each(function ($banner) {
    foreach(LaravelLocalization::getSupportedLanguagesKeys() as $i => $key) {
        factory(App\BannerTranslation::class)->create([
            'banner_id' => $banner->id,
            'locale' => $key,
        ]);
    }
});
...