Clean and readable code is an important aspect that distinguishes experienced programmers from beginners. Achieving this level of code quality requires experience and observation. While each framework has its own set of rules, I’ll focus on sharing some helpful principles within the context of the Laravel framework in this training course.
In our previous article, we discussed the REST Architecture which with its template enhance our code readability inside our controllers. Now, let’s explore the concept of mass assignment and the a tool called Request.
Before we begin, let’s take a moment to understand the output of the validate
function:
An essential aspect to understand about the validate function is that it exclusively returns an array of data that conforms to the rules you have specified. In other words, even if a user attempts to send an injected field to our server, the validate function will only return the information that we have defined! This helps to maintain the integrity and security of our server-side data processing:
$data = request()->validate([
'title' => 'required|min:3|max:120|unique:tasks,title',
'description' => 'nullable|min:3|max:255',
'expired_at' => 'nullable|date|after:now'
]);
Task::create($data);
See? It’s much more readable now. Let’s proceed and make a request to see the results:
The reason for the error you encountered is that models in Laravel, by default, prevent mass assignment to avoid accepting incorrect values. For example, if you haven’t properly defined the validation rules, sensitive user information like email or password could be set incorrectly. Laravel wants to ensure you’re aware of this potential issue. Luckily, we have two solutions to change this default behavior.
One solution is to use the fillable
property, which is an array of fields that you want to allow for mass assignment
protected $fillable = ['attribute'];
Alternatively, you can use the guarded
property, which works the opposite way by allowing you to specify the fields you don't want to be mass assignable:
protected $guarded = ['attribute'];
In our example, we need to include one of these properties in our model:
I personally prefer to use an empty array of guarded
Now, let’s explore another useful tool within Laravel called FormRequest, which allows us to separate request validation from our controller. This separation enhances code clarity and organization.
By creating a Request class, we can define the validation rules specific to that request, keeping our controller focused on handling the business logic.
To create a Request class, we can use the following artisan command:
php artisan make:request <request-name>
Additionally, Laravel provides convenient options when using the make:model
artisan command.
For example, you can include the -c
option to generate a new controller for the model, the -r
option to indicate that the generated controller should be a resource controller, the -m
option to create a new migration file for the model, and the -R
option to create new form request classes and automatically use them in the resource controller:
php artisan make:model <model-name> -c -r -m -R
Well, let’s back to our project add a request for our store function:
php artisan make:request StoreTaskRequest
Once created, you can open the StoreTaskRequest
file inside directory app/Http/Requests
and define your validation rules inside the rules method:
(Hint: I just drop unique rule for title to make it more sense! )
class StoreTaskRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'title' => 'required|min:3|max:120',
'description' => 'nullable|min:3|max:255',
'expired_at' => 'nullable|date|after:now'
];
}
}
By default, there is an authorize
function too that you can decide if an user is authorized to make this request, right? for now just set its value true
to let anyone has access to do request.
In addition to the rules, you can also customize the error messages by overriding the messages method in your FormRequest
file:
public function messages(): array
{
return [
'title.required' => 'Hey, don\'t forget to fill in your title!',
'title.min' => 'Oops! Your name should be at least three characters long.',
'description.min' => 'Hold up! The description too short!!!',
];
}
Now let’s use it!
To achieve that, we can inject the StoreTaskRequest
class into the store
method of our controller. This allows Laravel to handle the validation process automatically. If the validation fails, the user will be redirected back to the previous page, along with the error messages. On the other hand, if the validation passes successfully, the controller method will be executed.
In the picture above, to obtain validated data, you can use the validated
method. If you don't specify any keys as input for the validated function, it will return all the keys defined in the rules array. Alternatively, if you only want specific keys or an array of desired ones, you can simply pass them as input to the function. It's straightforward, right?
Now Let’s do same thing for our update method and make the UpdateTaskRequest
for update function:
php artisan make:request UpdateTaskRequest
And update UpdateTaskRequest
as follow:
class UpdateTaskRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'title' => 'required|min:3|max:120',
'description' => 'nullable|min:3|max:255',
'expired_at' => 'nullable|date|after:now'
];
}
}
Again to use that we only need to we can easily include the UpdateTaskRequest class as a parameter in the update method of our controller, But this time we have to apply the update method on binding model, as shown below:
public function update(Task $task, UpdateTaskRequest $request)
{
$task->update($request->validated());
return redirect("/tasks");
}
And that brings us to the end of this article. We’ve covered how to refactor our code and improve its clarity. In the next article, we’ll dive into authorization within Laravel. I hope you found this article enjoyable and informative. Stay tuned for more!
Top comments (2)
Very nice! Custom request classes are awesome
Yeah, They are very helpful and clean