What does "Mass Assignment" mean in Laravel?
Asked Answered
A

5

226

When I went through Laravel Document about Eloquent ORM topic part, I got a new term "Mass Assignment".

Document show How to do Mass Assignment and the $fillable or $guarded properties settings. But after went through that, I didn't have a clearly understand about "Mass Assignment" and how it works.

In my past experience in CodeIgniter, I also didn't hear about this term.

Does anyone have a simple explanation about that?

Agustinaah answered 9/3, 2014 at 7:14 Comment(1)
Some resources Wikipedia or Laravel 4 protects against this vulnerability in a single line of code. Or this post on vulnerabilityFrolicsome
C
286

Mass assignment is when you send an array to the model creation, basically setting a bunch of fields on the model in a single go, rather than one by one, something like:

$user = new User(request()->all());

(This is instead of explicitly setting each value on the model separately.)

You can use fillable to protect which fields you want this to actually allow for updating.

You can also block all fields from being mass-assignable by doing this:

protected $guarded = ['*'];

Let's say in your user table you have a field that is user_type and that can have values of user / admin

Obviously, you don't want users to be able to update this value. In theory, if you used the above code, someone could inject into a form a new field for user_type and send 'admin' along with the other form data, and easily switch their account to an admin account... bad news.

By adding:

$fillable = ['name', 'password', 'email'];

You are ensuring that only those values can be updated using mass assignment

To be able to update the user_type value, you need to explicitly set it on the model and save it, like this:

$user->user_type = 'admin';
$user->save();
Caddy answered 9/3, 2014 at 7:33 Comment(10)
Thanks for this answer, I quite do not understand who would do such thing as $user = new User(Input::all()); (as programmer) it is so uncontrolled (or in what scenario would be this helpful).Zonate
... it's not at all the point of the answer, it's to keep the answer short without hijacking it as a whole lesson on security etcCaddy
I got the point, and I am glad I found this answer. I am just curious in what scenario is line cited above (in my comment) useful. I mean without validation and all that stuff around.Zonate
so you think in response to a question titled 'What does “Mass Assignment” mean in Laravel?' I should have gone into detail about validation... it was a simple answer to the question without getting off track. Let's leave this as it is.Caddy
It does not matter what is point of the OP question I asked so I do not have to create new thread, and you keep talking about "why not" talk about it. I simply do not understand why would someone use line as you wrote it instead of $user = new User; $user->name = 'Neo';Zonate
@Zonate one may use User(Input:all) for shorter code that is more readable and easier to maintain. If you set your guards accordingly, then there is no security risk at all.Homemaking
@Caddy I just came across looking at the changes between L5.2 and L5.4 in L5.2 I was doing this Doctor::create($input); I see an notes in the PHPSTORM saying Non-static method 'create' should not be called statically is there is any deference between L5.2 and L5.4 in L5.2 hereHintze
@Kyslik, I'm experiencing an API Use Case that make good use of it. Some Models have sensible data that I want to control, but some are not so relevant. So all API\XXControllers don't have index(), show() and store() actions, but they inherit Controller that has index(), show(), store(). When calling index from any resource, it is treated variably in Controller according to resource model name. The same goes for create, $model = $EntityClass::create($request->all()); will do for all resources. If I want to control, I override index() in API\XXController.Diadromous
@KeitelJovin yea now, when one uses FormRequest (in your example you do not do that) you can use $request->all() because only validated fields will be present. Also its 4 years old conversation and I might say obsolete by now...Zonate
Yeah thanks for the tip. The point for me was for my own Frontend App, and if data is sensible, I will control both in Frontend and Backend, but if not then Frontend check is more that enough, and backend will spare me some codes.Diadromous
F
39

Mass assignment is a process of sending an array of data that will be saved to the specified model at once. In general, you don’t need to save data on your model on one by one basis, but rather in a single process.

Mass assignment is good, but there are certain security problems behind it. What if someone passes a value to the model and without protection they can definitely modify all fields including the ID. That’s not good.

Let's say you have 'students' table, with fields "student_type, first_name, last_name”. You may want to mass assign "first_name, last_name" but you want to protect student_type from being directly changed. That’s where fillable and guarded take place.

Fillable lets you specify which fields are mass-assignable in your model, you can do it by adding the special variable $fillable to the model. So in the model:

class Student extends Model {
      protected $fillable = ['first_name', 'last_name']; //only the field names inside the array can be mass-assign
} 

the 'student_type' are not included, which means they are exempted.

Guarded is the reverse of fillable. If fillable specifies which fields to be mass assigned, guarded specifies which fields are not mass assignable. So in the model:

class Student extends Model {
      protected $guarded = ['student_type']; //the field name inside the array is not mass-assignable
}

you should use either $fillable or $guarded - not both.

For more details open link:- Mass Assignment

Fideicommissum answered 5/4, 2018 at 10:12 Comment(1)
This is straight out of Matt Stauffer's book "Laravel Up & Running"Photocell
E
5

Mass assignment means you are filling a row with more than one column using an array of data. (somewhat of a shortcut instead of manually building the array) using Input::all().

Technically just from the top of my head. Fillable means what columns in the table are allowed to be inserted, guarded means the model can't insert to that particular column.

Notice that when you try to do a mass assignment with like, insert to a column named "secret", and you have specified that it is guarded, you can try to insert to it via the model, but it will never really get inserted into the database.

This is for security, and protection on your table when using the model. Mass assignment seems to be just a notice or warning that you didn't tell the model which are fillable and guarded and makes it vulnerable to some kind of attacks.

Encyclical answered 9/3, 2014 at 7:32 Comment(0)
U
2

This is when an array of data received is saved at once in a model.

Because of the security issues with this method in laravel, it's recommended you define the fields you wish the requested data to populate on the Model.

You can use the $fillable variable to define the fields you want to populate on the database table.

E.g

Protected $fillable = [‘username’, ‘dob’, ‘email’,];

When laravel detects you are mass assigning data, it forces you to define the fields you want to mass assign in the model class.

Someone can easily pass unwanted data into an html form to your database.

Unceasing answered 24/6, 2019 at 7:15 Comment(0)
G
0
There are two ways to handle this.

Laravel Eloquent provides an easy way to achieve this.
In your model class, add $fillable property and 
specify names of columns in the array like below:

enter image description here

You can achieve this by adding $guarded property in model class:

enter image description here

You can either choose $fillable or $guarded but not both.
Goodsell answered 31/3, 2021 at 11:51 Comment(1)
Please do not post images of code/error messages.Wellturned

© 2022 - 2024 — McMap. All rights reserved.