Seeding many-to-many relationship with model factory in laravel - column cannot be null error

懵懂的女人 提交于 2019-12-11 04:39:02

问题


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.


回答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.




回答2:


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());
});


来源:https://stackoverflow.com/questions/46908046/seeding-many-to-many-relationship-with-model-factory-in-laravel-column-cannot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!