Skip to content

weird unset functionality #2566

New issue

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

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

Already on GitHub? # to your account

Closed
bogdandubyk opened this issue Aug 21, 2023 · 2 comments · Fixed by #2578
Closed

weird unset functionality #2566

bogdandubyk opened this issue Aug 21, 2023 · 2 comments · Fixed by #2578

Comments

@bogdandubyk
Copy link

As far as I can see, laravel-mongodb overrides unset behavior to trigger drop functionality that makes a database query each time you run $moded->unset($field). That means if you have some model that goes through multiple services and making unsets in some of the services for example
In service 1:

$model->unset('blocked');

in service 2:

if ($model->price > 2) {
    $model->unset('margin');
}

in service 3 you are doing an actual save of the model

$model->save();

all this will lead to 3 queries, right? For small projects, it maybe not be an issue, but for big projects, it's a huge overhead for the database. and even worse, it's not a single transaction, and if execution interrupts somewhere it can bring side effects.

I tried to change the behavior of unset to not trigger the drop method but instead just to unset the attribute from the model, but in that case, during the model save, the model does not see changes because isDirty and getDirty methods do not compare with original data to find missing data and does not see changes.

It means you either you killing DB with multiple queries or can't unset the field with eloquent and only set it to null.

Is there any way to fix it???

@GromNaN
Copy link
Member

GromNaN commented Aug 22, 2023

Thank you for this feedback. I've also be surprised that such atomic operation could trigger a query to the database. Fixing this behavior will be a breaking change: projects will have to ensure that $model->save() is called after a $model->unset('blocked').

A solution would be to add an array of unset properties in the Model class and call $unset on this fields in Model::save(). The field name will have to be removed from this list of fields to unset when it is set again.

Note: this feature does not exist in Laravel Eloquent because you cannot unset a field in an SQL database.

(MongoDB Jira issue for tracking PHPORM-75)

@bogdandubyk
Copy link
Author

@GromNaN totally agrees with this, hope it'll be fixed by the library in some major release.

The workaround I decided to go with is to set the value to null instead of unset, in some sense it's the same. It's better than fighting with laravel/library on a live project

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

Successfully merging a pull request may close this issue.

2 participants