简体   繁体   English

Laravel 使用 Factory 进行一对一关系播种

[英]Laravel Seeding using Factory for one to one relation

I want to create a test data using laravel seed.我想使用 laravel 种子创建测试数据。 I can seed for one table.我可以为一张桌子播种。 Here is:这是:

ModelFactory.php:模型工厂.php:

/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
        'type' => '0'
    ];
});

UsersTableSeeder.php: UsersTableSeeder.php:

<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run() {
        factory(App\User::class, 50)->create()->each(function ($u) {
            $u->posts()->save(factory(App\Post::class)->make());
        });
    }
}

I have two tables which are users and user_information.我有两个表,分别是 users 和 user_information。 They have one-to-one relation.它们具有一对一的关系。 I want to seed user_information with users.我想为用户播种 user_information。 But i have no idea, how i can do...但我不知道,我该怎么做...

My models relation functions:我的模型关系函数:

User.php用户.php

public function userInformation() {
        return $this->hasOne('App\UserInformation', 'user_id', 'id');
    }

UserInformation.php用户信息.php

public function users() {
        return $this->belongsTo('App\User', 'user_id', 'id');
    }

Laravel version is 5.3 Laravel 版本是5.3

I followed these docs:我遵循了这些文档:

https://laravel.com/docs/5.3/seeding https://laravel.com/docs/5.3/seeding

https://laravel.com/docs/5.3/database-testing#writing-factories https://laravel.com/docs/5.3/database-testing#writing-factories

Answering because this came up in a Google search and might help others:回答是因为这是在谷歌搜索中出现的,可能会帮助其他人:

AFAIK the model hasn't got anything to do with seeding, that's used for query building and constraints . AFAIK 该模型与播种没有任何关系,它用于查询构建和约束

What can do is create a user , every time you call on your factory that requires the user_id .可以做的是创建一个用户,每次调用需要user_id工厂时

Credit to prodigy10 for this answer.这个答案归功于 prodigy10

$factory->define(User_Information::class, function ($faker) use ($factory) {
    return [
    'name' => $faker->company(),
    'user_id' => factory(User::class)->create()->id
    ];
});

For one-to-one relationships, its good practice to make the relationship methods singular对于一对一的关系,最好的做法是使关系方法单一

User.php用户名

public function userInformation() 
{
     return $this->hasOne('App\UserInformation', 'user_id', 'id');
}

UserInformation.php用户信息.php

public function user() 
{
        return $this->belongsTo('App\User', 'user_id', 'id');
}

Above solution for Laravel 8, userInformation factory will have :以上 Laravel 8 的解决方案,userInformation factory 将有:

'user_id' => User::factory()->create()->id,

if you need to create userInformation table only when there's a corresponding user, the above solution will seed new user_ids into the userinformation table and you may end up with more userinformation rows than users.如果您只需要在有相应用户时才创建 userInformation 表,上述解决方案会将新的 user_ids 播种到 userinformation 表中,您最终可能会得到比用户更多的用户信息行。 To fix this, you need to seed only UserInformation Factory seeder in DatabaseSeeder run method and not UserFactory.要解决此问题,您只需要在 DatabaseSeeder 运行方法中植入 UserInformation Factory 播种机,而不是 UserFactory。 it will automatically seed the users table.它将自动为用户表设定种子。

Alternatively, if you have the users table already defined and wants to seed userInformation table for your number of users.或者,如果您已经定义了 users 表并希望为您的用户数量设置 userInformation 表。

For Laravel 8, its is shown below:对于 Laravel 8,如下所示:

public function definition()
{
    $users = User::all();
    return [
        'name' => $this->faker->company,
        'user_id' => $this->faker->unique()->numberBetween(1, $users->count())
    ];

} }

Since its a one to one relationship.因为是一对一的关系。 You can generate the list of users and use unique and numberBetween functions to fill unique user_ids.您可以生成用户列表并使用 unique 和 numberBetween 函数来填充唯一的 user_id。

This works in Laravel 9. Amend your DatabaseSeeder.php such as:这适用于 Laravel 9. 修改您的DatabaseSeeder.php ,例如:

public function run()
    {
        User::factory(10)->create()->each(function ($user) {
            $phone = Phone::factory()->make();
            $user->phone()->save($phone); // phone() is hasOne ralationship in User.php        
        });
    }

You don't need to define user_id column in PhoneFactory.php .您不需要在PhoneFactory.php中定义user_id列。 The Laravel automatically saves corresponding user_id in the database. Laravel自动在数据库中保存对应的user_id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM