Search code examples
laravel-6laravel-seeding

Laravel 6.12 seeding factory don't see states


As usual the project needed seeds. And as usual I create a UserFactory, set it up, added to DatabasesSeeder and caught a error.

InvalidArgumentException  : Unable to locate [models] state for [App\Models\User]

but the default factory (I mean $factory->define(User::class, function (Faker $faker)) is working fine

UserTableSeeder.php

use Illuminate\Database\Seeder;
use App\Models\User;

class UserTableSeeder extends Seeder
{
    public function run()
    {
        factory(User::class, 50)->state('models')->create();
        factory(User::class, 50)->create();
    }
}

UserFactory.php

use App\Models\User;
use Faker\Generator as Faker;
use Illuminate\Support\Str;

$factory->define(User::class, function (Faker $faker) {
    //everything works fine here
});

$factory->defineAs(User::class, 'models', function (Faker $faker) {
    //exactly the same return except for a few string values
    //but 'Unable to locate [models] state for [App\Models\User]'
});

Solution

  • Ok. I was able to reproduce the error in my enviroment. Here's the problem. You gave the name models to you factory but called it as if it was a state. $factory->defineAs (Not documented) does not define a factory with state but just give a name to your factory. Factory States and Named Factories (yours) are two different things. This is why you can't seed your database like it was a State Factory.

    factory(User::class, 50)->state('models')->create();
    

    If you want to use $factory->defineAs function, replace the above line with

    factory(User::class,'models', 50)->create();
    

    Or

    (Recommended - Because it's well documented) If you still wish to be able to seed your database using ->state('models') (states), then change your UserFactory.php as follows

    use App\Models\User;
    use Faker\Generator as Faker;
    use Illuminate\Support\Str;
    
    $factory->define(User::class, function (Faker $faker) {
        //everything works fine here
    });
    
    $factory->state(User::class, 'models', function (Faker $faker) {
        //exactly the same return except for a few string values
        //but 'Unable to locate [models] state for [App\Models\User]'
    });
    

    Remark: you now define your second factory with $factory->state and not $factory->defineAs.