LoginSignup
9
8

More than 3 years have passed since last update.

Laravel Factory Relation Fakerの復習

Last updated at Posted at 2018-09-07

Laravelのバージョンを色々使ってると細かい所で、このバージョンの時は出来て、このバージョンのときは出来ないみたいな状況になるので、思った所を復習して置こうと思います。

今回は、テストコードを書く時に不可欠なfactory系でrelationのfactoryを使用時です。

まず、Model Factories が入ったのは、バージョン5.1からになります。

良くあるサンプルで、ブログとコメントのfactory例を上げてみます。

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->sentence,
        'body' => $faker->sentence
    ];
});
$factory->define(App\Comment::class, function ($faker) {
    return [
        'post_id' => factory(App\Post::class)->create()->id,
        'body' => $faker->sentence,
    ];
});

v5.1.2では、上記のfactory定義を行い、post_id をパラメーターで渡したとしても、元々Factoryで定義してあるModelも作られる現象が発生します。
その問題はこちらで述べています:https://github.com/laravel/framework/issues/9245

Factory::create(App\Comment::class, [
    'post_id' => $someGivenPostId
]);

その後 https://github.com/laravel/framework/pull/9387 のPull Reqestで5.1.3にマージされて、以下の形式で対応可能になりました。

// v5.1.3以降に$attributesが追加
$factory->define(App\Comment::class, function ($faker, $attributes) {

    $post_id = isset($attributes['post_id']) ? $attributes['post_id']: factory(App\Post::class)->create()->id;

    return [
        'post_id' => $post_id, 
        'body' => $faker->sentence,
    ];
});

しかし、上記だと複雑なRelationに対応出来たいとの事で https://github.com/laravel/framework/pull/12231/ のpull reqestでLaravel v5.2.2 で最終的な現在(書いてる時点でv5.7です)の形になってます。

// v5.2.16以降Clousreでrelationを定義
$factory->define(App\Post::class, function (Faker $faker) {
    return [
        'post_id' => function() {
            return factory(App\Post::class)->create()->id;
        },
        'body' => $faker->sentence,
    ];
});

これで以下の方法でも、余計なデーターが作られない様になりました。

factory(App\Comment::class, 10)->create(['post_id' => App\Post::find(1)]);

v5.1.3で追加された、$attribites もそのまま残されていますので、必要に応じて$attributesを元に分岐しても大丈夫です。

9
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8