laravelnested-setsfaker

Laravel: seeding a nested set table with Faker


I'm using Kalnoy/Nestedset and trying to seed my comments table using faker, but get "Array to string conversion" error.

The comment table looks like this:

Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('post_id');
            $table->text('body');
            $table->timestamps();
            $table->nestedSet();
        });

The comment factory:

use Faker\Generator as Faker;

$factory->define(
    App\Models\Comment::class,
    function (Faker $faker) {
        return [
        'user_id' => function () {
            return factory('App\Models\User')->create()->id;
        },
        'post_id' => function () {
            return factory('App\Models\Post')->create()->id;
        },
        'body' => $faker->paragraph,
        ];
    }
); 

And I can't really figure out what the seeder must look like. Here's my try:

public function run(Post $post)
    {
        $node = factory('App\Models\Comment'::class, 3)->create([

            'children' => [
                [
                    factory('App\Models\Comment'::class, 2)->create([
                        'post_id' => $post->id
                    ]),

                    'children' => [
                        [ factory('App\Models\Comment'::class, 1)->create([
                        'post_id' => $post->id
                            ]), 
                        ],
                    ],
                ],
            ],
        ]);
    }

}

I also want to make sure that the post id of children as the same as parent's, but now it returns null.


Solution

  • The keys of the array in the create method should be attributes that exist on your model. In your case children isn't an attribute on the Comment model.

    Using the example from the Using Factories documentation, you could rather create each comment and then use the children() relationship on the new models to create their children. For example:

    public function run(Post $post)
    {
        $node = factory('App\Models\Comment'::class, 3) // Create the root comments.
                ->create()
                ->each(function ($comment) use ($post) { // Add children to every root.
                    $comment->children()->saveMany(factory(App\Comment::class, 2)->make([
                        'post_id' => $post->id
                    ]))
                    ->each(function ($comment)  use ($post) { // Add children to every child of every root.
                         $comment->children()->saveMany(factory(App\Comment::class, 2)->make([
                            'post_id' => $post->id
                        ]));
                    });
                });