Posted on: August 01, 2025 11:58 AM
Posted by: Renato
Views: 136
Bypassing $fillable in Laravel Safely with forceFill()
Have you ever spent time using create() to save data in Laravel, only to realize later…
Fields like role or status didn't make it into the database?
You double-checked your data and everything seemed fine. But somehow, those fields just vanished when you looked into the DB.
Well, chances are you’re not yet familiar with Laravel’s mass assignment protection.
Behind the convenience of create() and update(), Laravel has a built-in protection mechanism that guards your models from blindly accepting untrusted input.
What Is Mass Assignment?
Mass assignment is a shortcut to fill multiple attributes of a model at once. For example:
User::create([ 'name' => 'Restu', 'email' => '[email protected]', 'role' => 'admin', ]);
But Laravel plays it safe. If you try to mass assign fields without telling Laravel which ones are allowed, it’ll silently ignore or block certain data — especially the sensitive ones.
To manage this, Laravel provides two main ways to control what can and can’t be filled:
1. $fillable: Whitelist Specific Fields
$fillable is a model property that defines which fields are allowed to be mass assigned.
Example:
protected $fillable = ['name', 'email'];
That means only name and email will be saved when using:
User::create([ 'name' => 'Restu', 'email' => '[email protected]', 'role' => 'admin', // ❌ will be ignored ]);
The role field will be skipped because it's not in the $fillable list.
When to use $fillable?
✅ When you know exactly which fields users are allowed to update
✅ When you want to be explicit and safe
✅ Perfect for user-submitted form data
2. $guarded: Blacklist Certain Fields
The opposite of $fillable, $guarded tells Laravel which fields cannot be mass assigned.
Example:
protected $guarded = ['role'];
Now all fields can be filled — except role.
Want to allow all fields without restriction?
Just do this:
protected $guarded = [];
That disables all mass assignment protection (use with caution!).
When to use $guarded?
✅ When your model has lots of fields and you only want to block a few
✅ Easier to manage for large models
✅ Suitable for internal systems (but still be careful!)
3. Hidden Feature: forceFill() to Bypass Protection
Now imagine this…
You’re working on backend logic where you need to fill a field like role. But that field isn’t included in $fillable — and for good reason: it's sensitive.
But here’s the thing:
✅ The data isn’t coming from the user
✅ You know it’s clean and safe
✅ You’re the one in full control
Instead of modifying $fillable, Laravel gives you a clean shortcut: forceFill().
Example:
$user = new User; $user->forceFill([ 'name' => 'Restu', 'email' => '[email protected]', 'role' => 'admin', ])->save();
With forceFill(), you can assign any field, regardless of $fillable or $guarded.
This often-overlooked method is super handy — especially for internal processing like seeders, jobs, or service classes.
Recap
Here’s a quick summary to help you choose the right approach:
- Use
$fillable
For defining which fields can be mass assigned. Ideal for handling form data or public inputs. Safe and explicit. - Use
$guarded
For blocking specific fields from being mass assigned. Great when your model has lots of fields and you only want to blacklist a few. - Use
forceFill()
When you need to bypass both$fillableand$guarded— but only when you trust the data source. Elegant and powerful for backend logic.
If you’ve been using create() without understanding what goes on behind the scenes, hopefully this article helped clear things up and saved you from those annoying "missing field" bugs.
Choose the approach that’s safest and most efficient for your case. Laravel is powerful — but only if you understand how to use its tools wisely. 😉
Fonte: Aqui!
Donate to Site
Renato
Developer