【问题标题】:Laravel - Seeding Many-to-Many RelationshipLaravel - 播种多对多关系
【发布时间】:2017-12-29 08:44:12
【问题描述】:

我有一个 users 表和一个具有 多对多 关系的 roles 表。这两个表连接到一个名为 role_user 的联结表。

This is a model of the tables and its connections.

以下是我的 Laravel 项目中的模型:

用户

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }
}

角色

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}

以下是 Laravel 项目中的 Factory 文件:

$factory->define(App\User::class, function (Faker\Generator $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
    ];
});

$factory->define(App\Role::class, function (Faker\Generator $faker) {
    return [
        'role' => $faker->realText($maxNbChars = 2),
        'description' => $faker->realText($maxNbChars = 20),
    ];
});

以下是 Laravel 项目中的 Seed 文件:

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

    factory(App\Role::class, 20)->create()->each(function ($u) {
        $u->users()->save(factory(App\User::class)->make());
    });
}

这应该填充 users 表和 roles 表,但我该如何填充 role_user 表? (我没有连接表的模型文件。)

我对此很陌生,因此我们将不胜感激。谢谢。

【问题讨论】:

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


【解决方案1】:

您可以在多对多关系中使用attach() or sync() method

有多种方法可以解决这个问题。这里是其中之一:

// Populate roles
factory(App\Role::class, 20)->create();

// Populate users
factory(App\User::class, 50)->create();

// Get all the roles attaching up to 3 random roles to each user
$roles = App\Role::all();

// Populate the pivot table
App\User::all()->each(function ($user) use ($roles) { 
    $user->roles()->attach(
        $roles->random(rand(1, 3))->pluck('id')->toArray()
    ); 
});

【讨论】:

  • 谁能解释为什么它选择 1 到 3 之间的随机而不是 1 到 20 之间的随机(因为角色中有 20 条记录,而不是 3 条)?
  • 也可以说 $roles->random(rand(1, $roles->count())) 从 1 到最大可用角色数量
  • 这将为用户附加 1 到 3 个随机角色。不要在 id 1 和 3 之间选择角色!我猜@peterm 想展示如何限制(最小和最大)您要附加的角色数量。
【解决方案2】:

对于播种机,您可以使用如下内容:

   for ($i = 0; $i < 50; $i++) {
        $user = factory(App\User::class)->create();

        $role = factory(App\Role::class)->create();

        DB::table('role_user')->insert([
            'user_id' => $user->id,
            'role_id' => $role->id
        ]);
    }

但通常您需要通过https://laravel.com/docs/5.4/eloquent-relationships#has-many-through 定义关系,例如有很多

然后你就可以使用了:

$user->roles()->save($role);

【讨论】:

    【解决方案3】:

    另一种方法是使用 saveMany() 函数

    public function run()
    {
    
       factory(App\User::class,3)->create();
    
       $roles = factory(App\Role::class,3)->create();
    
       App\User::All()->each(function ($user) use ($roles){
          $user->roles()->saveMany($roles);
       });
    }
    

    【讨论】:

    • 这将分别为每个用户附加3个新角色,这不是真正的多对多关系模型,而是实际上的多对一。
    【解决方案4】:

    更简洁的方法是:在为 App\User 和 App\Roles 定义工厂后,您可以像这样调用 afterCreating 方法:

    $factory->define(App\User::class, function ...);
    $factory->define(App\Role::class, function ...);
    
    $factory->afterCreating(App\User::class, function ($row, $faker) {
        $row->roles()->attach(rand(1,20));
    });
    

    然后在 Seeds 中您首先创建角色,然后是用户

    public function run()
    {
        factory(App\Role::class, 20)->create();
        factory(App\User::class, 50)->create();
    }
    

    现在您有 50 个用户,每个用户都附加一个角色。

    【讨论】:

      【解决方案5】:

      在 Laravel 8.x.x 中你可以简单地使用

      多对多关系附加/分离

      Eloquent 提供了使处理多对多关系更方便的方法。例如,假设一个用户可以有很多角色,而一个角色可以有很多用户。您可以使用 attach 方法通过在关系的中间表中插入一条记录来将角色附加到用户:

      use App\Models\User;
      
      $user = User::find(1);
      
      $user->roles()->attach($roleId);
      

      将关系附加到模型时,您还可以传递要插入中间表的附加数据数组:

      $user->roles()->attach($roleId, ['expires' => $expires]);
      

      【讨论】:

        猜你喜欢
        • 2019-11-17
        • 2019-01-05
        • 2021-10-29
        • 2015-12-23
        • 1970-01-01
        • 2020-11-05
        • 2020-10-08
        • 2013-05-02
        • 2021-05-08
        相关资源
        最近更新 更多