Please note: I am pretty new to laravel and programming in general.
So I am working on setting up a role system on my laravel project and I followed a tutorial and did eveything the same. My problem is that when registering it should register a new user with role 'User' and that's not happening. Also my database seeding isn't saving any role ID to my users.
My users table migration:
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->unsignedBigInteger('roles_id')->nullable();
$table->foreign('roles_id')->references('id')->on('roles');
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
My roles table migration:
class CreateRolesTable extends Migration
{
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
});
}
public function down()
{
Schema::dropIfExists('roles');
}
}
My role_user table migration:
class CreateRoleUserTable extends Migration
{
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('role_id')->unsigned();
$table->bigInteger('user_id')->unsigned();
});
}
public function down()
{
Schema::dropIfExists('role_user');
}
}
My DataBaseSeeder:
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
// Role comes before User seeder here.
$this->call(RoleTableSeeder::class);
// User seeder will use the roles above created.
$this->call(UserTableSeeder::class);
}
}
RoleTableSeeder
use Illuminate\Database\Seeder;
use App\Role;
class RoleTableSeeder extends Seeder
{
public function run()
{
$role_worker = new Role();
$role_worker->name = 'worker';
$role_worker->save();
$role_admin = new Role();
$role_admin->name = 'admin';
$role_admin->save();
$role_user = new Role();
$role_user->name = 'user';
$role_user->save();
}
}
UserTableSeeder
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use App\Role;
use App\User;
class UserTableSeeder extends Seeder
{
public function run()
{
$role_worker = Role::where('name', 'worker')->first();
$role_admin = Role::where('name', 'admin')->first();
$role_user = Role::where('name', 'user')->first();
$worker = new User();
$worker->name = 'Worker User';
$worker->email = 'worker@worker.com';
$worker->password = Hash::make('password');
$worker->save();
$worker->roles()->attach($role_worker);
$admin = new User();
$admin->name = 'Admin user';
$admin->email = 'admin@admin.com';
$admin->password = Hash::make('password');
$admin->save();
$admin->roles()->attach($role_admin);
$user = new User();
$user->name = 'Regular user';
$user->email = 'user@user.com';
$user->password = Hash::make('password');
$user->save();
$user->roles()->attach($role_user);
}
}
Tables after migrating/seeding
So again, my problem is that when registering it should register a new user with role 'User' and that's not happening. Also my database seeding isn't saving any roles_id to my users.
You have a pivot relationship; there is no need to put the roles_id
column on your users. Drop these lines from your migration:
CreateUsersTable
// $table->unsignedBigInteger('roles_id')->nullable();
// $table->foreign('roles_id')->references('id')->on('roles');
Everything else looks good; your roles
and users
tables are being populated, and the pivot is setting the correct values for user_id
and role_id
. Now, you'd access the user's roles via
$user->roles
// Should return a `Collection` of roles, based on the number of records in `role_user`
As a sidenote, you generally don't have an auto-incrementing id on a pivot
table, since the data is constantly changing, and you're unlikely to reference role_user.id
at any point, so you can also drop this line:
CreateRoleUserTable
// $table->bigIncrements('id');
Edit: The bigger issue here is a fundamental lack of understanding on how pivot
and many-to-many
relationships work (and that's ok, you said you're new to Laravel and programming).
I believe you're trying to set roles_id
on users
to role_user.id
, but that's fundamentally incorrect. That is not how this type of relationship works. It uses an intermediate table role_user
, which has user_id
and role_id
to link many instances of users
to many instances of roles
.
If you were to set roles_id
on users
, you could only ever have a single role
, at which point this would cease to be a many-to-many
, and would be a simple link between users
and roles
, which would render the role_user
table completely unnecessary.