Adding Relations to Laravel Factory Model

纵然是瞬间 提交于 2019-11-27 18:05:08

问题


I'm trying to add a relation to a factory model to do some database seeding as follows - note I'm trying to add 2 posts to each user

public function run()
{
   factory(App\User::class, 50)->create()->each(function($u) {
         $u->posts()->save(factory(App\Post::class, 2)->make());
   });
}

But its throwing the following error

Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::s  
ave() must be an instance of Illuminate\Database\Eloquent\Model, instance 
of Illuminate\Database\Eloquent\Collection given

I think its something to do with saving a collection. If re-write the code by calling each factory model for the post separately it seems to work. Obviously this isn't very elegant because if I want to persist 10 or post to each user then I'm having to decalare 10 or lines unless I use some kind of for loop.

public function run()
{
   factory(App\User::class, 50)->create()->each(function($u) {
     $u->posts()->save(factory(App\Post::class)->make());
     $u->posts()->save(factory(App\Post::class)->make());
   });
}

* UPDATED *

Is there any way to nest the model factory a 3rd level deep?

public function run()
{
   factory(App\User::class, 50)
       ->create()
       ->each(function($u) {
           $u->posts()->saveMany(factory(App\Post::class, 2)
                    ->make()
                    ->each(function($p){
                          $p->comments()->save(factory(App\Comment::class)->make());
          }));
   });
}

回答1:


Try this. It worked for me:

factory(\App\Models\Auth\User::class, 300)->create()->each(function ($s) {
                    $s->spots()->saveMany(factory(\App\Models\Spots\Parking::class, 2)->create()->each(function ($u) {
                            $u->pricing()->save(factory(\App\Models\Payment\Pricing::class)->make());
                    }));
                    $s->info()->save(factory(\App\Models\User\Data::class)->make());
            });



回答2:


Since Laravel 5.6 there is a callback functions afterCreating & afterMaking allowing you to add relations directly after creation/make:

$factory->afterCreating(App\User::class, function ($user, $faker) {
    $user->saveMany(factory(App\Post::class, 10)->make());
});

$factory->afterMaking(App\Post::class, function ($post, $faker) {
    $post->save(factory(App\Comment::class)->make());
});

Now

factory(App\User::class, 50)->create()

will give you 50 users with each having 10 posts and each post has one comment.




回答3:


For a 3rd level nested relationship, if you want to create the data with the proper corresponding foreign keys, you can loop through all the results from creating the posts, like so:

factory(App\User::class, 50)->create()->each(function($u) {
    $u->posts()
        ->saveMany( factory(App\Post::class, 2)->make() )
        ->each(function($p){
            $p->comments()->save(factory(App\Comment::class)->make());
        });
});


来源:https://stackoverflow.com/questions/32540845/adding-relations-to-laravel-factory-model

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