Home > Software design >  Newbie question about controller and request in Laravel in my case
Newbie question about controller and request in Laravel in my case

Time:10-28

I am new in Laravel, what I try to achieve is very simple thing, I would like to use FormRequest provided by Laravel to do validation of the request, but I encounter some puzzles (which I am sure is easy things to solve if you are experienced in Laravel).

Here is what I tried:

I have route maps to controller:

Route::put('user/{name}', 'UserController@show');

I can get the name parameter in show function:

class UserController {
  public function show($name)
  {
     // validtion rules to apply
    ...
  }
}

I have validation rules to apply to the request, so I decided to create form request by php artisan make:request ShowRequest, which creates the form request class:

class ShowRequest extends FormRequest {
  public function authorize()
  {
     return true;
  }

  public function rules()
    {
        return [
            // my validation rules here
        ];
    }
}

Since I have above request class, so I refactored the show function in controller to receive the ShowRequest .

class UserController {
  public function show(ShowRequest $request)
  {
     // now I don't need validtion rules in this function 
     // but how can I access the 'name' parameter now
    ...
  }
}

I have two questions to ask:

  1. Inside the refactored show function, how can I now access the route parameter name ?

  2. Now if I want to throw custom exception when validation fails, how should I do that?

CodePudding user response:

You still can add the parameter $name in the show() method of your controller as it's part of the routed url more than the validated form/data. (recommanded)

class UserController {
    public function show(ShowRequest $request, $name)
    {
        //...
    }
}

You can also access it from the request object

class UserController {
    public function show(ShowRequest $request)
    {
        $request->input('name');
    }
}

As for the error messages (not the exception) you can add the messages() method to your ShowRequest::class

class ShowRequest extends FormRequest
{
    /**
     * @return array
     */
    public function messages()
    {
        return [
            'name.required' => 'The name is required',
            'name.numeric' => 'The name must be a number',
            //...
        ];
    }
}

If you instead need to validate that the name catched by the route is only composed of letter OR really exists as a field in your DB (like a slug of a post) you need to add some validation in your route declaration.

  1. Setup a route that catches request only if it is composed of letters.
Route::get('/user/{name}', 'Controller@show')->where(['name' => '[a-z] ']);
  1. Setup a route that catches request only if the "name" exists in DB:

User.php

Class User //..
{
    /**
     * Get the route key for the model.
     *
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'name';
    }
}

web.php

//
Route::get('/user/{user:name}', 'Controller@show');

And adapt your controller to take a user directly

class UserController {
    public function show(ShowRequest $request, User $user)
    {
        //...
    }
}

CodePudding user response:

You can access the values of the Form Request using this

$validated = $request->validated();

The $validated will have all the values which had been validated by the FormRequest.

To answer your second question, if you want to throw custom validation, you can always use the following

throw ValidationException::withMessages(['name' => 'Something is wrong']);
  • Related