Laravel 工厂关系...尊重 create() 或 make()

Joh*_*nny 6 php phpunit laravel eloquent

根据 Laravel关于在模型工厂中定义关系文档

您还可以使用工厂定义中的闭包属性将关系附加到模型。例如,如果您想在创建 Post 时创建一个新的 User 实例,您可以执行以下操作:

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

我遇到的问题是create()关系定义中的引用。在我看来,这不属于这里。

如果我想保留与数据库的关系,它会很好用:

factory(App\Post::class)->create();
Run Code Online (Sandbox Code Playgroud)

通过直接运行上面的代码,一个新的App\Post和一个新的App\User将被创建并持久化到数据库中。

但是,如果我只想new启动模型而不是通过运行将任何东西(根本)持久化到数据库中:

factory(App\Post::class)->make();
Run Code Online (Sandbox Code Playgroud)

它在某种程度上做我想做的事。一个新的App\Post实例被创建但不持久化,但是App\Comment被创建并持久化到数据库中。


在我看来,我真正想要的是这样的:

$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;
        }
    ];
});
Run Code Online (Sandbox Code Playgroud)

最终结果是我希望相关数据尊重我从通话顶部开始尝试做的事情。做一切。或者创造一切。


我在这里做错了吗?或者这是目前不存在的东西?

谢谢!

小智 2

您需要为相关模型提供lazy() 方法!

至少在 Laravel 5.5 中是这样。

我在这里找到你的问题,因为我也遇到了同样的问题。感谢 Laravel 编写精美的代码,我找到了答案——lazy() 就定义在 XDebug 所带的 make() 之上——而且我已经尝试过,它似乎有效。

这就是我正在做的:

$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,
    ];
});
Run Code Online (Sandbox Code Playgroud)

Lazy() 是一个有趣的生物,它返回一个闭包,所以你不能这样做,factory(App\Image::class)->lazy()->id但我仍然看到它成功设置了正确的 image_id 和artist_id。

我当然希望您早在这之前就找到了解决方案,但这也许会对其他人有所帮助!

  • 看起来很酷!我需要这个,但它对我不起作用...如果我使用factory(...)->lazy()定义我的工厂,那么,当我使用make(User::class)时,它仍然在调用create( )在引擎盖下... (2认同)