1

Given that I have the following tables:

  • users
  • questions
  • tags
  • question_tag my pivot table with two fields: question_id & tag_id

and these are my model relationships:

User

public function questions()
{
    return $this->hasMany(Question::class);
}

Question

public function user()
{
    return $this->belongsTo(User::class);
}

public function tags()
{
    return $this->belongsToMany(Tag::class);
}

Tag

public function questions()
{
    return $this->belongsToMany(Question::class);
}

I have setup the database model factory correctly for each models.

With my seeder, here's what I am trying to achieve:

  1. Seed 10 dummy users
  2. For each dummy user, seed 10 dummy questions
  3. For each dummy question, associate it with up-to 5 random tags

To achieve the above three goals, I wrote the following database seeder:

// Seed dummy users
factory(App\User::class, 10)->create()->each(function($user)
{
    // With dummy questions
    $user->questions()->saveMany(factory(App\Question::class, 10)->make()->each(function($question)
    {
        // With dummy tags
        $question->tags()->sync(factory(App\Tag::class, 5)->make());
    }));
});

When this runs, I am getting the following error:

[Illuminate\Database\QueryException] SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'question_id' cannot be null (SQL: i nsert into question_tag (question_id, tag_id) values (, 1))

[PDOException] SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'question_id' cannot be null

How do you seed a pivot table, whilst creating records via the database model factory?


This question is related to another question I asked - but now I am getting a different error.

Latheesan
  • 23,247
  • 32
  • 107
  • 201

2 Answers2

1

I've solved it like this:

<?php

use Illuminate\Database\Seeder;

class DummyDataSeeder extends Seeder
{
    public function run()
    {
        // Seed dummy tags
        factory(App\Tag::class, 10)->create();
        $tagIds = DB::table('tags')->pluck('id')->toArray();

        // Seed dummy users
        factory(App\User::class, 10)->create()->each(function($user) use($tagIds)
        {
            // With dummy questions
            $user->questions()->saveMany(factory(App\Question::class, 3)
            ->create(['user_id' => $user->id])->each(function($question) use($tagIds)
            {
                // With dummy tags
                $question->tags()->sync(array_random($tagIds, mt_rand(1, 5)));
            }));
        });
    }
}

Maybe there's a better a way to do this; but this is working for me.

Latheesan
  • 23,247
  • 32
  • 107
  • 201
0

When you use saveMany method, you should set Eloquent model instance as parameter like this.

$user->questions()->saveMany(factory(App\Question::class, 10)->make())->each(function($question)
{
    // With dummy tags
    $question->tags()->sync(factory(App\Tag::class, 5)->make());
});
mk-tool
  • 325
  • 1
  • 4
  • 10