在 Laravel 工厂中,与 "state" 和 "defineAs" 有什么区别?

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

在 Laravel 的工厂中,使用方法 state 和方法 defineAs 有什么区别?

state 只是基本方法的扩展而 defineAs 是完全不同的定义吗?能举几个例子让大家更容易理解吗?

方法statedefineAs的用途完全不同。

definedefineAs

您使用 define 方法为模型注册一个工厂,该方法通过 class 和回调提供。例如,如果您正在为 User 模型创建一个工厂,那么您将像这样注册它:

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

然后你会这样调用工厂:

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

然而,有时您可能希望使用名称而不是 class 来注册工厂,这样您就可以像这样调用工厂:

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

这就是 defineAs 的用武之地:defineAs 接受 class(例如:App\User::class 一个名称。例如:

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

defineAs 没有记录,但您可以在 Eloquent source.

中找到它

工厂状态

Factory States 用于生成具有特定属性集的模型:

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

例如,您的 User 模型可能有一个额外的 is_admin 字段,用于确定用户是否是管理员。您可以创建一个状态,以允许通过工厂生成管理员用户。

首先定义状态(admin 是名称):

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

然后在生成您的用户时,您传入 admin 状态:

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

这意味着您的 User 模型可以有一个工厂,支持许多不同的 类型 用户;您可以在同一个工厂内为被禁止的用户或拥有与其帐户相关联的图片的用户创建一个状态。这是额外的好处,因为这意味着开发人员在使用工厂时无需关心底层结构,如果底层结构发生变化(例如:is_admin 变为 administrator_at),只需关注工厂即可改变了。

前面的回答说 defineAs 就像一个别名或 shorthand 名字,但这是错误的!如果你:

factory('user')->create(); //it won't work

defineAs 和状态几乎相同,略有不同。 在 5.2 之前的版本中,状态被称为状态 https://laravel.com/docs/5.2/testing#model-factories

因此 defineAs 在创建模型时创建不同的模型类型,基于原始模型来设置通用属性,如下所示:

$factory->define(App\User::class, function ($faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->email,
        'password' => str_random(10),
        'remember_token' => str_random(10),
        'admin' => false,
    ];
});

$factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) {
    $user = $factory->raw(App\User::class);

    return array_merge($user, ['admin' => true]);
});

虽然 states 也在做同样的事情,但方式更时尚:

$factory->state(App\User::class, 'address', function ($faker) {
    return [
        'admin' => true,
    ];
});

或者甚至没有回调,只是一个数组:

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

另一个区别是 define 会触发一个事件(afterCreating),一旦对象被保存在数据库中就会被调用,而 states 会触发一个事件 afterCreatingState。 此外,您可以创建一个具有多个状态的对象,如下所示:

factory(App\User::class)->states('admin', 'disable')->create()