Skip to content

[5.6] Fix: soft-delete does not sync original#24400

Merged
taylorotwell merged 4 commits into
laravel:5.6from
TBlindaruk:soft-delete
Jun 4, 2018
Merged

[5.6] Fix: soft-delete does not sync original#24400
taylorotwell merged 4 commits into
laravel:5.6from
TBlindaruk:soft-delete

Conversation

@TBlindaruk

@TBlindaruk TBlindaruk commented May 31, 2018

Copy link
Copy Markdown
Contributor

Actually, it is resubmitted for #24399

When we run a soft delete, then actually the original array is not changed, and it causes a problem for restoring after the soft deleting in one model.

So the steps to reproduce the bug:

  1. find in the database
  2. soft delete the found model
  3. restore the foud model
  4. find the same model in database

Expectations: model will be restored
Actual result: the model is soft deleted

I have added a test.

    /**
     * @throws \Exception
     */
    public function testUpdateModelAfterSoftDeleting()
    {
        $now = Carbon::now();
        $this->createUsers();

        /** @var SoftDeletesTestUser $userModel */
        $userModel = SoftDeletesTestUser::find(2);
        $userModel->delete();
        $this->assertEquals($now->toDateTimeString(), $userModel->getOriginal('deleted_at'));
        $this->assertNull(SoftDeletesTestUser::find(2));
        $this->assertEquals($userModel, SoftDeletesTestUser::withTrashed()->find(2));
    }
    
    /**
     * @throws \Exception
     */
    public function testRestoreAfterSoftDelete()
    {
        $this->createUsers();
    
        /** @var SoftDeletesTestUser $userModel */
        $userModel = SoftDeletesTestUser::find(2);
        $userModel->delete();
        $userModel->restore();
        
        $this->assertEquals($userModel->id, SoftDeletesTestUser::find(2)->id);
    }

@TBlindaruk
TBlindaruk force-pushed the soft-delete branch 2 times, most recently from 179b6fc to fcbdd50 Compare May 31, 2018 18:25
@taylorotwell

Copy link
Copy Markdown
Member

I feel like we used to have the code this way and it got removed because of some other bug it causes? Did you search through the old PRs for soft deletes?

@TBlindaruk

TBlindaruk commented Jun 1, 2018

Copy link
Copy Markdown
Contributor Author

@taylorotwell ,

  • I have looked through the commits on the Database/Eloquent/SoftDeletes.php file. And I can not fond the syncOriginal method.

  • have searched in all the repository commits - also not found a syncOriginal()

  • In the old PR for soft deleting I can not find the problem related to this too

@TBlindaruk

Copy link
Copy Markdown
Contributor Author

I have the little bit changed the calling syncOrigin method to as it in the 'save' method.

@TBlindaruk

Copy link
Copy Markdown
Contributor Author

@taylorotwell ?

@taylorotwell
taylorotwell merged commit bbc9de8 into laravel:5.6 Jun 4, 2018
@TBlindaruk
TBlindaruk deleted the soft-delete branch June 4, 2018 18:34
@mlanin

mlanin commented Jun 20, 2018

Copy link
Copy Markdown
Contributor

This fix destroys original logic completely. original stores the state of the model when it was retrieved. It helps to check what was changed.
With this fix we can't do it, because it seems like model wasn't changed at all. original and attributes store the same values, and both contain deleted_at. This behaviour completely broke my code!

@TBlindaruk

Copy link
Copy Markdown
Contributor Author

@mlanin , sorry ;(

@GrahamCampbell GrahamCampbell changed the title [5.6] Fix: soft-delete does not sync original. [5.6] Fix: soft-delete does not sync original Jun 20, 2018
@edbentinck

Copy link
Copy Markdown
Contributor

I really don't understand this change. It causes the 'deleted' model event to behave differently to 'created' and 'updated'. As @mlanin says, with this change you can no longer retrieve changed values.

Since you can manually call syncOriginal anyway, surely it would be more desirable to leave the behavior of deleted in line with the other model events than to break this behavior for everyone without offering an opt-out:

$userModel->delete();
$userModel->syncOriginal();
$userModel->restore();

@TBlindaruk

Copy link
Copy Markdown
Contributor Author

@edbentinck you can create PR for revert this.

@mfn

mfn commented Aug 31, 2018

Copy link
Copy Markdown
Contributor

I feel like we used to have the code this way and it got removed because of some other bug it causes? Did you search through the old PRs for soft deletes?

@TBlindaruk please revert, see also Taylors concern

@TBlindaruk

Copy link
Copy Markdown
Contributor Author

@edbentinck Thanks!

@robsonvn

Copy link
Copy Markdown

The deleted_at field should be synced after update for sure, but not all the atributes. We have to find a middle term and not pretent that the bug doesn't exists.

        $updated = $query->update($columns);

        if ($updated) {
            foreach(array_keys($columns) as $column) {
                $this->syncOriginalAttribute($column);
            }
        }

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

Successfully merging this pull request may close these issues.

6 participants