Bypassing $fillable Safely with forceFill() in Laravel

July 2, 2025

Bypassing $fillable Safely with forceFill() in Laravel

Ever used create() in Laravel and noticed some fields like role or status didn’t save? That’s because Laravel’s mass assignment protection silently ignores non-whitelisted attributes.

🔐 What Is Mass Assignment?

Mass assignment lets you set multiple model attributes in one go, e.g.:

User::create([
  'name' => 'John',
  'email' => '[email protected]',
  'role' => 'admin', // This won’t get saved if not fillable
]);

🛡️ Two Ways to Control Fillable Fields

1. $fillable (Whitelist)

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

Only listed fields are allowed for mass assignment.

2. $guarded (Blacklist)

protected $guarded = ['role'];

Everything is fillable except the blacklisted attributes.

⚡ Enter forceFill()

When you trust your data source (e.g., from an internal service, seeder, or job), you can bypass fillable/guarded protection using:

$user = new User;

$user->forceFill([
  'name' => 'John',
  'email' => '[email protected]',
  'role' => 'admin',  // Will be assigned regardless of $fillable
])->save();

No need to adjust your $fillable or $guarded, and it's safe when used properly.

✔️ When to Use Each

  • $fillable: For trusted user input (forms, APIs).
  • $guarded: When many fields are fillable except a few.
  • forceFill(): For backend logic with trusted data.

Using create() without understanding mass assignment may result in “missing fields” — use the right tool for the job. Laravel is powerful when used with understanding.

The Ultimate Managed Hosting Platform