prodigy10's avatar

Model Factories Relations

I am having a bit of trouble transitioning from TestDummy to the new Model Factories. How do you create the related model factories. Let's say you have users and companies. Each company is owned by 1 user. How do I go creating the user_id field?


$factory->define( User::class, function ($faker) {
    return [
        'name' => $faker->firstName(),
        'email' => $faker->email,
        'password' => bcrypt("password")
    ];
});

$factory->define(Company::class, function ($faker) use ($factory) {



    return [

    'name' => $faker->company(),
    'owner_id' => XXXXXX

    ];
});

0 likes
12 replies
mstnorris's avatar

First you define both factory methods for your models, and then you'd do something like the example below (from the docs).

http://laravel.com/docs/5.1/testing#model-factories

Adding Relations To Models

You may even persist multiple models to the database. In this example, we'll even attach a relation to the created models. When using the create method to create multiple models, an Eloquent collection instance is returned, allowing you to use any of the convenient functions provided by the collection, such as each:

$users = factory('App\User', 3)
           ->create()
           ->each(function($u) {
                $u->posts()->save(factory('App\Post')->make());
            });
18 likes
prodigy10's avatar

@mstnorris I need a way of doing it on the factories definitions. Not when I am already using them on testing or seeding.

mstnorris's avatar

@prodigy10 you'd just do something like: (I'm not sure of the exact syntax, but Jeffrey has a lesson on it.) I'll try to find it.

$factory->define('App\User', function ($faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->email,
        'profile_id' => $factory->create('App\Profile')->id,
        'password' => str_random(10),
        'remember_token' => str_random(10),
    ];
});

https://laracasts.com/series/whats-new-in-laravel-5-1/episodes/5

prodigy10's avatar
prodigy10
OP
Best Answer
Level 2

@mstnorris Jeffrey doesn't really goes over that part on the tutorial. I got it working with this code:

$factory->define( User::class, function ($faker) {
    return [
        'name' => $faker->firstName(),
        'email' => $faker->email,
        'password' => bcrypt("password")
    ];
});

$factory->define(Company::class, function ($faker) use ($factory) {



    return [

    'name' => $faker->company(),
    'owner_id' => factory(User::class)->create()->id

    ];
});
15 likes
devinfd's avatar

@mstnorris @prodigy10 Be wary of using 'profile_id' => $factory->create('App\Profile')->id in your factory definitions. It works fine but if you need to override the profile_id value the original definition ($factory->create('App\Profile')->id) will still be created first before your override is merged in and may cause issues for you later on. I've raised this issue on github https://github.com/laravel/framework/issues/9245 but have not heard a response yet.

5 likes
mstnorris's avatar

@devinfd I saw your issue on GitHub and I hope that is sorted soon. While it is still in development it shouldn't be an issue, and unless you are writing 100s of these things then whatever solution they go with, I'm sure it can be swapped out.

prodigy10's avatar

@mstnorris the "newer syntax" was not a minor detail, if I would have known the "newer syntax" I would not have opened the question in the first place.

InCraft's avatar

May be will help you

factory(App\Category::class, 7)
            ->create()
            ->each(function(App\Category $category) {
                factory(App\Item::class, 10)
                    ->create([
                        'category_id' => $category->id,
                    ]);
            });
7 likes
helioh3's avatar

how to create a factory for N: N relationships ... how to feed the PIVOT table

1 like

Please or to participate in this conversation.