Search code examples
laravellaravel-5factoryfakerlaravel-seeding

Laravel - Seeding Many-to-Many Relationship


I have a users table and a roles table that has a many-to-many relationship. These two tables are connected to a junction table called role_user.

This is a model of the tables and its connections.

Below are the Models in my Laravel project:

User

namespace App;

use Illuminate\Database\Eloquent\Model;

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

Role

namespace App;

use Illuminate\Database\Eloquent\Model;

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

Below is the Factory file in the Laravel project:

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

Below is the Seed file in the Laravel project:

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

This should populate the users table and the roles table but how do I go about populating the role_user table? (I don't have a Model file for the junction table.)

I'm very new at this so any help would be appreciated. Thanks.


Solution

  • You can use attach() or sync() method on a many-to-many relationship.

    There are multiple ways you can approach this. Here one of them:

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