Eloquent Mass Assignment: Protection Patterns
Eloquent Mass Assignment: Protection Patterns
Eloquent Mass Assignment: Protection Patterns
Tip: Use $fillable Explicitly
protected $fillable = ['title', 'content', 'published'];
Only listed fields can be mass-assigned via create() or update().
Gotcha: $guarded = [] is Dangerous
protected $guarded = []; // All fields are fillable
This allows users to set ANY field, including is_admin or role. Never use with user input.
Tip: fill() vs create()
$post = new Post();
$post->fill($data); // Doesn't save
$post->save();
fill() applies mass assignment rules without persisting.
Gotcha: forceFill() Bypasses Protection
$post->forceFill(['is_admin' => true])->save();
Use only in trusted contexts like seeders or migrations.
Tip: Dynamic Fillable
public function getFillable(): array
{
return $this->isAdmin() ? ['*'] : ['title', 'content'];
}
Gotcha: update() on Existing Models
$post->update($request->all());
Only updates fillable fields. Non-fillable fields are silently ignored.
Tip: Use cursor() for Memory-Neutral Iteration
When exporting 100K rows, get() loads everything into memory. cursor() uses yield and keeps memory flat regardless of row count. Perfect for artisan commands.
Tip: whereHas() vs load() — Two Different Things
whereHas() filters the parent query by relationship existence. load() eager-loads relationships AFTER the query. Mixing them up is a common source of logic bugs.
Gotcha: withCount() Adds a Subquery
withCount('comments') runs a correlated subquery on every row. On large tables, this can be slower than a separate query. Profile before relying on it.
Senior Insight
Mass assignment protection is one of Laravel's best security features, yet I still see $guarded = [] in production codebases. A single missing $fillable or $guarded definition can expose your entire database to mass assignment attacks via API payloads. I've made it a non-negotiable rule in every team I've led: all models must have explicit $fillable arrays, and $guarded = [] is never approved in code review.
Source: Laravel Docs (https://laravel.com/docs/eloquent), Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/eloquent)