Laravel101: The Role of Mass Assignment in Eloquent Model

Kazem Mirzaei
5 min readAug 10, 2023

--

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 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!

--

--

Kazem Mirzaei
Kazem Mirzaei

Written by Kazem Mirzaei

Software Engineer | Full Stack, PHP, Laravel, React, Vue, Docker

No responses yet