フリーランスのためのネットビジネス専門学校 ネットで独立開業を目指す人を応援
フリーランスのためのネットビジネス専門学校 ネットで独立開業を目指す人を応援

Laravel Factory Relation Fakerの復習

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

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

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

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

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

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

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

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

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

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

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

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

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

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

factory(AppComment::class, 10)->create(['post_id' => AppPost::find(1)]);

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

[紹介元] PHPタグが付けられた新着投稿 – Qiita Laravel Factory Relation Fakerの復習

コメント

記事に戻る

コメントを残す