Laravel:当表有两个外键时,为具有关系的数据库表播种

Posted

技术标签:

【中文标题】Laravel:当表有两个外键时,为具有关系的数据库表播种【英文标题】:Laravel: Seeding Database table with relationship When the table has two foreign key 【发布时间】:2020-10-04 12:14:49 【问题描述】:

我正在使用 laravel 工厂方法来填充我的数据库表。我有三个模型,它们之间的关系如下:

   **User model**

class User extends Authenticatable

    public function books() 
        return $this->hasMany('App\Book', 'user_id', 'id');
    

    public function ratings() 
        return $this->hasMany('App\Rating', 'user_id', 'id');
    



    **Book Model**

    class Book extends Model

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

    public function ratings() 
        return $this->hasMany('App\Rating', 'book_id', 'id');
    

 **Rating Model**

class Rating extends Model


    public function book() 
        return $this->belongsTo('App\Book', 'book_id', 'id');
    
    public function user() 
        return $this->belongsTo('App\User', 'user_id', 'id');
    

我对模型 Book 和 Rating 的工厂定义如下所示:

$factory->define(Book::class, function (Faker $faker) 
    return [
        'title' => $faker->title,
        'description' => $faker->sentence
    ];
);

$factory->define(Rating::class, function (Faker $faker) 
    return [
        'rating' => $faker->numberBetween(1,5)
    ];
);

数据库表如下所示:

用户表:

id,name,email,password

书桌:

id,user_id,title,description

评分表:

id,user_id,book_id,rating

调用工厂的代码如下:

public function run()
       
        //create 10 users
        $user = factory(App\User::class,10)->create();

        // create 2 books for each user
        $user->each(function ($user) 
            $book = $user->books()->saveMany(factory(App\Book::class,2)->make());
            );

        );

因此,通过这种运行方法,我可以创建 10 个用户,每个用户有两本书。但我也想让每本书由 3 个不同的用户评分。那么我应该在上面的方法中添加什么额外的代码来实现这一点。

【问题讨论】:

【参考方案1】:

我有一个简单的接近方法,你可以考虑

//create 10 users
$user = factory(App\User::class,10)->create();
$id_arr = Arr::pluck($user , 'id'); // get user id array

// create 2 books for each user
$user->each(function ($user) use($id_arr) 
    $books = $user->books()->saveMany(factory(App\Book::class,2)->make());
    $shuffle_id = Arr::shuffle($id_arr); // shuffle user_id each time create user successfully
    // add 3 rates for each book with different user
    $books->each(function ($book) use($shuffle_id) 
        $book_id = $book['id'];
        for ($i=0; $i<3; $i++)
            $user_id = $shuffle_id[$i]; // get id in first 3 of shuffle_id array (this will make sure, user_id will never be duplicated
            factory(App\Rate::class)->create(['book_id'=>$book_id, 'user_id' => $user_id]);
        
    );
);

希望对你有帮助

【讨论】:

只有我需要做的是全局定义数组变量,否则在每个函数中它会说未定义的变量。其他一切正常。非常感谢你。 是的,谢谢,我忘了用use()给回调函数传递参数。我会更新我的答案

以上是关于Laravel:当表有两个外键时,为具有关系的数据库表播种的主要内容,如果未能解决你的问题,请参考以下文章

Laravel中具有两个外键字段的数据库一对多

Laravel Eloquent 用于数据透视表,一个表有 2 个外键,另一个表有 1 个外键

添加外键时首先在EF核心代码中生成双id字段

Laravel 5.5中的一对多关系

Laravel关系,一个数据库有两个外键

当模型具有外键时,ModelState.IsValid 为 false