Search code examples
phplaravelauthenticationroles

Assigning role in Laravel with registration


Hi Im fairly new to Laravel and what I am trying to achieve is to assign user role to User while registering. I have successfully seeded and created my User table which contains role_id. I have created login and logout but when I try to create register for some reason the role_id that I am passing from URL parameter in my case: {{hostAuth}}/register/1 where '1' should be role_id.

For my RegisterRequest this is how it looks currently:

public function rules(): array
{
    return [
        'name' => 'required|string|max:150',
        'email' => 'required|email|max:150|unique:users',
        'password' => 'required|confirmed',
        'role_id' => 'required'
    ];
}

public function getData(int $role_id): array
{

    $this->merge([
        'role_id' => $role_id,
    ]);

    return $this->validated();
}

Here is my Controller for that part:

 public function __invoke(RegisterRequest $request)
{
    User::create($request->getData(1));
}

public function register(RegisterRequest $request, int $role_id)
{
    User::create($request->getData($role_id));
}

And lastly web route (bcs im using SPA):

Route::post('/register/{role_id}', [RegisterController::class, 'register']);

When I try to run it this is the error I'm getting:

  {
    "message": "The role id field is required.",
    "errors": {
        "role_id": [
            "The role id field is required."
        ]
    }
}

When I dd the role_id I get the correct number but for some reason the role_id is not being added to the part where I validate my data, only the 3 arguments that I passed in my body show, yeah this is my body of the request as well:

{
"name": "test",
"email": "[email protected]",
"password": "password",
"password_confirmation": "password"
}

Like I mentioned Im fairly new to Laravel so if there is a better/cleaner approach than this I'm all ears or if someone can help me figure out what I am doing here wrong. Thanks in advance :D

Update: I also tried this method:

Route::post('/register/registerCustomer', [RegisterController::class, 'registerCustomer']);
Route::post('/register/registerMechanic', [RegisterController::class, 'registerMechanic']);

With:

public function registerCustomer(RegisterRequest $request)
{
    $role_id = $request->input('role_id', 1);

    User::create(array_merge($request->validated(), ['role_id' => $role_id]));
}

public function registerMechanic(RegisterRequest $request)
{
    $role_id = $request->input('role_id', 2);

    User::create(array_merge($request->validated(), ['role_id' => $role_id]));
}

Same issue:

"message": "SQLSTATE[HY000]: General error: 1364 Field 'role_id' doesn't have a default value (Connection: mysql, SQL: insert into `users` (`name`, `email`, `password`, `updated_at`, `created_at`) values (test, [email protected], $2y$12$bx3UZQqOG8cO91FTz5mOeeT/

Solution

  • Before using the create method, you will need to specify either a fillable or guarded property on your model class. The error is probably because you don't have the role_id there.

    From the Laravel docs: By default, attributes that are not included in the $fillable array are silently discarded when performing mass-assignment operations. In production, this is expected behavior; however, during local development it can lead to confusion as to why model changes are not taking effect.

    If you wish, you may instruct Laravel to throw an exception when attempting to fill an unfillable attribute by invoking the preventSilentlyDiscardingAttributes method.