使用Model Factories定义Laravel外键,One to One&一对多关系,无需创建不必要的模型

时间:2016-11-27 12:43:19

标签: php laravel laravel-5 faker laravel-seeding

最近,我一直试图通过Model Factories和Faker使用Laravel播种来播种我的数据库。

对于简单的模式,让它工作是一件轻而易举的事情:)。但是,在处理涉及外键和表关系的复杂数据库模式时遇到了一些问题:

  • 一对一
  • 一对多
  • 多对多

...与链接中描述的内容类似: Laravel 5.1 foreign keys in model factory

在本主题中,official documentation建议运行如下数据库种子:

public function run()
{
    factory(App\User::class, 50)->create()->each(function ($u) {
        $u->posts()->save(factory(App\Post::class)->make());
    });
}

...但是这个解决方案存在一个问题:当处理许多数据库表并运行多个种子(它们之间有很多关系)时,创建许多不必要的模型是很常见的方法。例如,如果我们在上述示例之前运行了PostsTableSeeder.php,那么所有这些帖子都不会链接到用户,并且永远不会用于测试和开发......

因此,为了找到处理这种情况的方法,我找到了一个适用于我的功能性解决方案,并避免了那些不必要的创造“孤儿”的问题。模型...

我想和大家分享,所以答案中只是解释了:)。

2 个答案:

答案 0 :(得分:22)

所以这是我的解决方案:

该示例处理:

  • 用户&个人资料(用于说明一对一关系)
  • 用户&帖子(用于说明一对多关系)

    // ONE TO ONE relationship (with Users already created)
    $factory->define(App\Profile::class, function (Faker\Generator $faker) {
        return [
            'user_id' => $faker->unique()->numberBetween(1, App\User::count()),
            // Rest of attributes...
        ];
    });
    
    // ONE TO MANY relationship (with Users already created)
    $factory->define(App\Posts::class, function (Faker\Generator $faker) {
        $users = App\User::pluck('id')->toArray();
        return [
            'user_id' => $faker->randomElement($users),
            // Rest of attributes...
        ];
    });
    

答案 1 :(得分:0)

这是一种解决方案,可以使关系比分配随机用户更好,特别是如果您需要向此模型发送额外信息。

$factory->define(App\Post::class, function (Faker\Generator $faker) {
    $user = factory('App\Models\User')->create(['email' => 'email@test.com,]);
    // do your relationships here (...)
    return [
        'user_id' => $user->id,
        'title'   => $faker->sentence,
        'body'    => $faker->paragraph,
        ];
    }

我看到另一个使用匿名函数的例子

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

来源:https://laracasts.com/series/laravel-from-scratch-2017/episodes/22