Ir al contenido principal

Laravel Database Query Builder and Model fillable array

 artisan tinker eloquent to do an update ... set ... = value

Respuesta rápida

To update a specific record in Laravel using Artisan Tinker and Eloquent, retrieve the model instance and assign the new value to the attribute, then call the save() method.

$user = App\Models\User::find(1);
$user->name = 'New Name';
$user->save();

Alternatively, you can use the update() method on a query builder instance for a direct database update without loading the model:

App\Models\User::where('id', 1)->update(['name' => 'New Name']);

Key Considerations:

  • Mass Assignment: Ensure the attribute being updated is in the model's $fillable array, or use fill() before save().

  • Collections: If using ::all() or ::get(), you receive a collection. You must iterate through it or use ::find() to get a single model instance before calling save().

  • Persistence: Assigning a value (e.g., $user->name = '...') only changes the object in memory; you must call save() or update() to persist changes to the database.

Can I use the update method of a query builder with an attribute which is not in the fillable array?

Yes. The query builder's update() method completely bypasses $fillable and $guarded — it operates at the raw query level, not the Eloquent model level, so no mass-assignment check is performed.

// This works even if 'role' is NOT in $fillable:
User::where('id', 1)->update(['role' => 'admin']);

This is the same reason insert() and update() on the query builder skip events, mutators, and mass assignment protection.

If you want the mass-assignment check to still apply, you must hydrate a model instance first:

// This WILL respect $fillable / $guarded:
User::find(1)->update(['role' => 'admin']); // throws MassAssignmentException if 'role' is guarded

Or use forceFill() to explicitly bypass it on a model instance:

User::find(1)->forceFill(['role' => 'admin'])->save();

Comentarios