$fillable and $guarded don't work when use update()? #39305
-
Hi, I use Laravel 8.41.0 and I have a question: Why I have a table named Now I added In controller, I use
the Another, if i use
But, when using
the According to docs, it should work but actually not. Anything I missing? English is not my native language; please excuse typing errors. Thanks very much! Update: even try upgrade Laravel to 8.66.0, it is still. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Mass assignment only works with eloquent models. When calling // Calling update on a builder will simply execute an update query
// -> "update `groups` set `name` = ?, `updated_at` = ? where `id` = ?"
$builder = Group::where('id', $id); // Illuminate\Database\Eloquent\Builder
$builder->update(...);
// When first retrieving an eloquent model a select query will retrieve the data, then hydrate it into an eloquent model
// and then you can do all sorts of stuff, like updating the model
$model = Group::firstWhere('id', $id); // App\Models\Group
$model->update(...); In the second example mass assignment is applied. So if you really need mass assignment you will have to retrieve the model first. Keep in mind that this will in result in 2 queries (one for the select and one for the update): Group::firstWhere('id', $id)->update([
'name' => $request->input('name'),
'updated_at' => "1999-10-22 10:23:09"
]); Updating multiple records will result in n+1 (one query to select all groups and than one update for each group): Group::all()->each->update([
'updated_at' => now()
]); If you have 100 groups this will also hydrate 100 eloquent models. While Group::query()->update([
'updated_at' => now()
]); If you want to utilize mass assignment but don't want 101 queries and 100 hydrations you can filter out the inputs you don't want: $guarded = (new Group)->getGuarded();
$data = [
'name' => $request->input('name'),
'updated_at' => "1999-10-22 10:23:09"
];
$data = collect($data)
->reject(fn ($value, $key) => in_array($key, $guarded))
->toArray();
Group::query()->update($data); |
Beta Was this translation helpful? Give feedback.
Mass assignment only works with eloquent models. When calling
update
on a query builder instance no eloquent model is received and laravel doesn't know whats in the fillable and guarded property.