Seeding pivot table with Laravel 5.5 model factory - mb_strtolower() expects parameter 1 to be string, array given

杀马特。学长 韩版系。学妹 提交于 2019-12-11 06:18:00

问题


Given that I have the following tables:

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

and my App\Question model has the following relationships:

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

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

I've created the following factories:

database/factories/UserFactory.php

$factory->define(App\User::class, function (Faker $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('123456')
    ];
});

database/factories/QuestionFactory.php

$factory->define(App\Question::class, function (Faker $faker) {
    static $user_id;

    return [
        'user_id' => $user_id,
        'subject' => $faker->sentence(15),
        'body' => $faker->paragraph(10)
    ];
});

database/factories/TagFactory.php

$factory->define(App\Tag::class, function (Faker $faker) {
    return [
        'name' => str_slug($faker->words(mt_rand(1, 2))),
        'description' => $faker->sentence()
    ];
});

I tried to use it all together in my dummy data seeder like this:

class DummyDataSeeder extends Seeder
{
    public function run()
    {
        // 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, 3)->make());
            }));
        });
    }
}

When I run the seeder, I get the following error:

[ErrorException] mb_strtolower() expects parameter 1 to be string, array given

Is this not possible to do in model factory? Do I need to use a different approach?


回答1:


I think you need to use belongsToMany for your pivot Table

In Your Question model

public function tags()
 {
  return $this->belongsToMany(Tag::class,'question_tag','tag_id','question_id');
 }

same with your Tag Model

public function questions()
{
 return $this->belongsToMany(Question::class,'question_tag','question_id','tag_id');
}

also, You need to change

 $question->tags()->sync(factory(App\Tag::class, 3)->make());

to

$tags = factory(App\Tag::class, 3)->make();
$tagIds = Tag::select('id')->get()->toArray();
 $question->tags()->sync($tagIds);

which means you need to pass IDs in Sync argument.




回答2:


From fzaninotto/Faker readme:

words($nb = 3, $asText = false) // array('porro', 'sed', 'magni').

will return array

Laravel str_slug()

The str_slug function generates a URL friendly "slug" from the given string: $slug = str_slug('Laravel 5 Framework', '-');

str_slug expects string

In your database/factories/TagFactory.php you need to fix the line:

'name' => str_slug($faker->words(mt_rand(1, 2))),

to

'name' => str_slug(implode(' ', $faker->words(mt_rand(1, 2)))),

or maybe

'name' => str_slug($faker->sentence(mt_rand(1, 2))),


来源:https://stackoverflow.com/questions/46900408/seeding-pivot-table-with-laravel-5-5-model-factory-mb-strtolower-expects-par

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