I currently learn Laravel 5.8 and created database where users can have two roles: admin or user stored in roles table. I tried to populate role_users intermediate table but Laravel doubles rows and seeds wrong data like this: Crazy ROLE_USER Table. role_id should be only 1 or 2. user_id should be unique. What did I do wrong?

User model:

public function roles() {
    return $this->belongsToMany('App\Role', 'role_users')->withTimestamps(); 
}

Role model:

public function roles() { 
    return $this->belongsToMany('App\User', 'role_users')->withTimestamps();
}

create_role_users_table migration:

Schema::create('role_users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('role_id');
    $table->unsignedBigInteger('user_id');
    $table->timestamps();
});

RoleUsersFactory factory:

$factory->define(RoleUser::class, function (Faker $faker) {
    return [
        'role_id'   => Role::all()->random()->id,
        'user_id'   => User::all()->random()->id,];
});

RoleTableSeeder seeder:

$role_user = new Role();
$role_user->role = 'user';
$role_user->save();
$role_admin = new Role();
$role_admin->role = 'admin';
$role_admin->save();

DatabaseSeeder seeder:

$this->call(RoleTableSeeder::class);
factory(User::class, 5)->create()->each(function($user) {
    $user->roles()->save(factory(RoleUser::class)->make());   
});

2 Answers

0
Sandeep Sudhakaran On Best Solutions

create a role then.

$role = Role::create(['role_name' => 'admin']);

use attach()

factory(User::class, 100)->create()->each(function ($user) use ($role ) {
        $role ->users()->attach($user);
});

Try the above code.

This will create 100 different users with admin as role. you can add other roles like this.

hope this suite for you.

0
Douwe de Haan On

You have the wrong relationships (you state that you want all the users to have a single role, which should be a BelongsTo / HasMany).

On the User model, have this method:

public function role() {
    return $this->belongsTo('App\Role');
}

Create this method on the Role model:

public function users() {
    return $this->hasMany('App\User');
}

Delete the migration you made where the role_users table is created and create a new migration with the following code:

Schema::table('users', function(Blueprint $table) {
    // remove the nullable if a user HAS to have a role at all times
    $table->unsignedBigInteger('role_id')->nullable();
}

Now, as a last step, the seeders. Your Role-seeder is correct. You shouldn't change that. Change your User-seeder to the following:

factory(User::class, 100)->create(['role_id' => Role::all()->random()->id]);

This will create a database with 100 users, where each has a role of admin or normal user. You can get all the users attached to a role with $role->users and get the role of a user with $user->role.