0

I'm working on a Laravel project and trying to seed the database by using model factories.

I have a Banners table and related BannerTranslations model to hold translated values. The project will have 3 languages. I'm trying to seed 5 dummy values into Banners table relating to BannerTranslations. In theory i expect 3 translation rows created for each Banner row, which should result 15 entries (3x5) to the BannerTranslations table in the end. But i get 45 entries instead. Each translation row is seeded 3 times instead of 1. I'm sure i'm missing something very obvious but i can't figure out what.

translation migration:

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,
    ];
});

and 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,
        ]);
    }
});

This results 3 same key rows per translation ('en','en','en','de','de','de','fr','fr','fr') instead of ('en','de','fr'). And because of this it returns a unique contstraint error.

megavolkan
  • 197
  • 1
  • 2
  • 13

2 Answers2

2

I'm not well acquainted with using factories but looking at you're and checking the docs, your problem is with the second parameter in factory(App\BannerTranslation::class, $lang_count). You're already looping through LaravelLocalization::getSupportedLanguagesKeys() and in for each one you're creating 3 records.

Give this a try:

$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,
        ]);
    }
});
Julio Motol
  • 763
  • 5
  • 22
0

I used this method. it can help you too.

            Download::factory(26)
            ->create()
            ->each( function($download) {
                foreach(Language::where(['status' => 1])->get() as $language){
                    DownloadTranslation::factory(1)->state(['language_code' => $language['code']])
                    ->create()
                    ->each(function($download_translation) use (&$download) {
                        $download->translations()->save($download_translation)->make();
                    });
                }
            });
Fahrettin Aksoy
  • 109
  • 1
  • 5