web-dev-qa-db-fra.com

Laravel - Seeding plusieurs à plusieurs relation

J'ai une table users et une table roles table qui a une relation plusieurs-à-plusieurs . Ces deux tables sont connectées à une table de jonction appelée role_user.

Ceci est un modèle des tables et de leurs connexions.

Voici les modèles de mon projet Laravel:

Utilisateur

namespace App;

use Illuminate\Database\Eloquent\Model;

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

Rôle

namespace App;

use Illuminate\Database\Eloquent\Model;

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

Ci-dessous se trouve le fichier Factory dans le projet Laravel:

$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),
    ];
});

Ci-dessous se trouve le fichier Seed dans le projet Laravel:

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());
    });
}

Cela devrait remplir la table users et la table roles mais comment puis-je remplir le role_user table? (Je n'ai pas de fichier modèle pour la table de jonction.)

Je suis très nouveau dans ce domaine, donc toute aide serait appréciée. Merci.

14
Bilal Khawar

Vous pouvez utiliser attach() ou sync() méthode dans une relation plusieurs-à-plusieurs.

Il existe plusieurs façons d'aborder cela. Voici l'un d'eux:

// 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()
    ); 
});
34
peterm

Une autre façon consiste à utiliser la fonction 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);
   });
}
7
user1853220

Juste pour un semoir, vous pouvez utiliser quelque chose comme ceci:

   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
        ]);
    }

Mais normalement, vous devez définir une relation comme celle qui en a plusieurs à travers https://laravel.com/docs/5.4/eloquent-relationships#has-many-through

Ensuite, vous pourrez utiliser:

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