Finally, let's move to the second role: teachers. Let's also enable registration for them. We will have a radio input on the register page to select a role.
First, we must take care of the backend. Let's introduce a role. We will have a Role
Model and add a role relationship to the User
Model. So, first, the Model with Migrations.
php artisan make:model Role -mphp artisan make:migration "add role id to users table"
app/Models/Role.php:
class Role extends Model{ protected $fillable = [ 'name', ];}
database/migrations/xxx_create_roles_table.php:
Schema::create('roles', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps();});
database/migrations/xxx_add_role_id_to_users_table.php:
Schema::table('users', function (Blueprint $table) { $table->foreignId('role_id')->constrained();});
app/Models/User.php:
class User extends Authenticatable{ use HasFactory, Notifiable; protected $fillable = [ 'name', 'email', 'password', 'role_id', ]; // ...}
Now, let's seed student
and teacher
roles.
database/seeders/DatabaseSeeder.php:
use App\Models\Role; class DatabaseSeeder extends Seeder{ public function run(): void { Role::create(['name' => 'student']); Role::create(['name' => 'teacher']); }}
Refresh the migrations with the seed.
php artisan migrate:fresh --seed
Next, let's add a radio input to select a role.
resources/views/auth/register.blade.php:
<x-guest-layout> <form method="POST" action="{{ route('register') }}"> // ... <!-- Role --> <div class="mt-4"> <x-input-label for="role_id" :value="__('Register as:')" /> <label> <input type="radio" name="role_id" value="1" checked /> Student </label> <label class="ml-2"> <input type="radio" name="role_id" value="2" /> Teacher </label> <x-input-error :messages="$errors->get('role_id')" class="mt-2" /> </div> <div class="flex items-center justify-end mt-4"> <a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="{{ route('login') }}"> {{ __('Already registered?') }} </a> <x-primary-button class="ms-4"> {{ __('Register') }} </x-primary-button> </div> </form></x-guest-layout>
Finally, we must save the role to the database.
app/Http/Controllers/Auth/RegisteredUserController.php:
class RegisteredUserController extends Controller{ // ... public function store(Request $request): RedirectResponse { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class], 'password' => ['required', 'confirmed', Rules\Password::defaults()], 'role_id' => ['required', 'in:1,2'], ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), 'role_id' => $request->role_id, ]); event(new Registered($user)); Auth::login($user); return redirect(route('student.timetable', absolute: false)); }}
Notice: for the validation, we use the in
validation rule instead of exists
because we can only register with these two roles. We want users to refrain from registering with an admin role.
After registering with the teacher role in the database, we see that the correct role is set.
But now the teacher is still landing in the Student area? In the next lesson, we will start separating student and teacher areas.