Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
m-zanetti opened this issue Aug 22, 2020 · 5 comments

Comments

@m-zanetti
Copy link

  • 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

protected function isGuardableColumn($key)
{
if (! isset(static::$guardableColumns[get_class($this)])) {
static::$guardableColumns[get_class($this)] = $this->getConnection()
->getSchemaBuilder()
->getColumnListing($this->getTable());
}
return in_array($key, static::$guardableColumns[get_class($this)]);
}

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

@m-zanetti
Copy link
Author

m-zanetti commented Aug 23, 2020

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

@driesvints
Copy link
Member

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

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

@m-zanetti
Copy link
Author

@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()?

@driesvints
Copy link
Member

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

@m-zanetti
Copy link
Author

m-zanetti commented Aug 24, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants