Laravel factory relationship ... respect create () or make ()

According to Laravel, the documentation for defining relationships in model factories is :

You can also attach relationships to models using Closure attributes in factory definitions. For example, if you want to create a new user instance when creating a Post, you can do the following:

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

      


The problem I am facing is the reference to create()

in the definition of the relationship. It seems to me that this does not belong here.

This works great if I want to keep my relationship with the database:

factory(App\Post::class)->create();

      

By running the code directly above this, a new App\Post

and a new one will be created App\User

and both are stored in the database.

But if I just want to new

raise the model (s) and not save anything (at all) to the database by running:

factory(App\Post::class)->make();

      

It does what I want, up to a certain point. A new instance App\Post

is created but not saved, but it App\Comment

is created and stored in the database.


It seems to me that I really want something like this:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            // here I only want to declare the relationship,
            // not decide whether I want to create() or make()
            // the relationship, something like:
            return factory(App\User::class)->createOrMake()->id;

            // or perhaps something like:
            return factory(App\User::class)->id;
        }
    ];
});

      

The end result is that I want the relevant data to respect what I am trying to do from the top of the call, down. Do everything. Or create everything.


Am I doing something wrong here? Or is it something that does not currently exist?

Thank!

+3


source to share


2 answers


Try this approach

I had the same problem as yours, this solution worked for me but couldn't find the cause.



$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            $user = factory(App\User::class)->make();
            $id = $user->id;
            $user->save();
            return $id;
        }
    ];
});

      

0


source


You need a lazy () method for your sibling models!

At least in Laravel 5.5.

I found your question here because I had the same problem. I found the answer thanks to Laravel's nicely written code - lazy () was defined just above make () XDebug took me to - and I tried it and it seems to work.

This is what I am doing:



$factory->define(App\ArtItem::class, function (Faker $faker) {
    return [
        // 'id' => $faker->randomDigit,
        'slug' => $faker->unique->word,
        'artist_id' => factory(App\Artist::class)->lazy(),
        'image_id' => factory(App\Image::class)->lazy(),
        'created_at' => $faker->dateTime,
        'updated_at' => $faker->dateTime,
        'deleted_at' => $faker->dateTime,
    ];
});

      

Lazy () is an interesting creature that returns a closure, so you can't do it factory(App\Image::class)->lazy()->id

, but I can still see that it has successfully set the correct images_and_and_and_and_and_and_

I certainly hope you found a solution long before this, but maybe it will help someone else!

0


source







All Articles