phplaravellaravel-seeding

In Laravel Factories, what is the difference from "state" and "defineAs"?


What is the difference, in Laravel's Factories, from using the method state and the method defineAs?

Is state just an extension of the base method and defineAs a whole different definition? Could you present some examples to make it easier to understand?


Solution

  • The methods state and defineAs serve completely different purposes.

    define and defineAs

    You register a factory for a model using the define method which you provide with a class and a callback. For example, if you are creating a factory for the User model then you would register it like this:

    $factory->define(App\User::class, function (Faker $faker) {
        // set values here
    });
    

    Then you would call the factory like so:

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

    However, sometimes you may wish to register a factory using a name instead of the class, so that you could call the factory like this:

    factory('user')->make();
    

    That's where defineAs comes in: defineAs accepts a class (e.g: App\User::class) and a name. For example:

    $factory->define(App\User::class, 'user', function (Faker $faker) {
        // set values here
    });
    

    defineAs isn't documented but you can find it in the Eloquent source.


    Factory States

    Factory States are used for generating models with a specific set of attributes:

    States allow you to define discrete modifications that can be applied to your model factories in any combination.

    For example, your User model may have an additional is_admin field which determines if the user is an admin or not. You can create a state to allow for a user who is an admin to be generated through the factory.

    First you define your state (where admin is the name):

    $factory->state(App\User::class, 'admin', [
        'is_admin' => true,
    ]);
    

    Then when generating your user you pass in the admin state:

    factory(App\User::class)->states('admin')->make();
    

    This means that you can have a single factory for your User model that supports many different types of User; you could create a state for banned users, or users who have a picture associated with their account, all within the same factory. This is extra beneficial because it means developers don't need to be concerned with the underlying structure when using factories, and if the underlying structure changes (e.g: is_admin becomes administrator_at) only the factory needs to be changed.