Framework: [6.x] No mass update of json field ['json_field->json_attr' => 'new value'] even if json_field is not guarded

Created on 22 Aug 2020  路  5Comments  路  Source: laravel/framework


  • Laravel Version: 6.18.35
  • PHP Version: 7.2.33
  • Database Driver & Version: MySQL 5.7.31

Description:

Update specific keys of a json field using mass assignment doesn't work even if column is not in _$guarded_.
Adding json colum to _$fillable_ doesn't work too.

I think the problem is due to https://github.com/laravel/framework/blob/bf734872f172acdd3c839713897c655821e2df8e/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php#L193-L202
that it search json_field->json_key in table column names list even if _$key_ is not in _$garded_.

I use json field to store dinamic data and i don't know all json keys, so i can't add the _json_field->json_key_ to _$fillable_ variable.

Steps To Reproduce:

  • create a module with _$guarded_ and no _$fillable_ ex: protected $guarded = ['id'];
  • in a controller try to update model with partial json key:
$myModel->update([
    'description' => 'new description', 
    'json_field->json_key' => 'new value'
]);

_desciption_ is updated but _json_field->json_key_ isn't updated

Most helpful comment

Hi @driesvints yes i read post, but even if json column is fillable i can't update json_column->json_key because isn't a real table column.

It seems i've two options only:

  1. read the column json and update casted array key and doing update of json column
  2. try to add at fillable array any json_column->json_key that i need to update

I can't do option 2 because my json column have dynamic keys.

I thought that fix should avoid update of json keys if json column is guarded and not avoid json key mass update, thanks for your reply.

All 5 comments

for now i'm overriding _isGuardableColumn()_ in models class where i need control of _$garded_ with:

class MyModel extends Model
{
...
    /**
     * Override Illuminate\Database\Eloquent\Concerns\GuardsAttributes trait function
     *
     * @param string  $key
     *
     * @return bool
     */
    protected function isGuardableColumn($key)
    {
        return true;
    }
...
}

It's not the best, because is not a patch or a solution, it's only a workaround to disable fix without downgrade version

This isn't possible anymore with the recent security update.

See https://blog.laravel.com/security-release-laravel-61835-7240

@driesvints excuse me but you are saying that in model class is not possible update single key of json column even if is not guarded?

I'm a bit confused. To do it i must use DB::update()?

Have you read the blog post? We don't support mass assignment through JSON this way. Try adding the column to your fillable array.

Hi @driesvints yes i read post, but even if json column is fillable i can't update json_column->json_key because isn't a real table column.

It seems i've two options only:

  1. read the column json and update casted array key and doing update of json column
  2. try to add at fillable array any json_column->json_key that i need to update

I can't do option 2 because my json column have dynamic keys.

I thought that fix should avoid update of json keys if json column is guarded and not avoid json key mass update, thanks for your reply.

Was this page helpful?
0 / 5 - 0 ratings