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

SoftDelete::runSoftDelete does not take into account overridden Model::setKeysForSaveQuery #28022

Closed
elnur-ibr opened this issue Mar 26, 2019 · 10 comments
Labels

Comments

@elnur-ibr
Copy link
Contributor

elnur-ibr commented Mar 26, 2019

  • Laravel Version: 5.8.4
  • PHP Version: 7.2.4
  • Database Driver & Version: MySql

Description:

SoftDelete::runSoftDelete does not take into account overridden Model::setKeysForSaveQuery method.
I use this for multi-tenancy purposes. Or for use composite primary keys.

Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Shop extends Model
{
    use SoftDeletes;

    public $primaryKey= 'shop_id';

    protected function setKeysForSaveQuery(Builder $query) {
        $query
            ->where('user_id', '=', $this->getAttribute('user_id'))
            ->where('shop_id', '=', $this->getAttribute('shop_id'));

        return $query;
    }
}

When running below code:

$shop = Shop::find(1);
$shop->delete();

Expected query:
UPDATE shop SET deleted_at = ?, Shop.updated_at = ? WHERE shop_id = ? AND user_id = ?

Actual query:
UPDATE shop SET deleted_at = ?, SHOP.updated_at = ? WHERE shop_id = ?

Solution is to replace below line

<?php

namespace Illuminate\Database\Eloquent;

trait SoftDeletes
{
     ...
     protected function runSoftDelete()
    {
        $query = $this->newModelQuery()->where($this->getKeyName(), $this->getKey());
        ...
     }
     ...
}

To

$query = $this->setKeysForSaveQuery($this->newModelQuery());

@elnur-ibr elnur-ibr changed the title SoftDelete:: does not take into account overridden Model::setKeysForSaveQuery SoftDelete::runSoftDelete does not take into account overridden Model::setKeysForSaveQuery Mar 26, 2019
@driesvints
Copy link
Member

Why would update Shop be expected here?

@elnur-ibr
Copy link
Contributor Author

@driesvints it was mistype. Corrected.

@driesvints
Copy link
Member

Heh, I'm not sure that setKeysForSaveQuery is meant to be used like this. Can't you just overwrite the runSoftDelete method if you want?

@elnur-ibr
Copy link
Contributor Author

elnur-ibr commented Mar 29, 2019

Yes you can overwrite runSoftDelete but I think if I am overwrite Model::setKeysForSaveQuery so SoftDelete::runSoftDelete should take it into account.

Please see below setKeysForSaveQuery and runSoftDelete methods below. The where part practically same.

protected function setKeysForSaveQuery(Builder $query)
    {
        $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());

        return $query;
    }
protected function runSoftDelete()
    {
        $query = $this->newModelQuery()->where($this->getKeyName(), $this->getKey());
        ...
     }
     ...

@driesvints
Copy link
Member

The question is if this has side effects. @staudenmeir do you maybe see any from the changes above?

@staudenmeir
Copy link
Contributor

I agree that this should be changed. We should also use setKeysForSaveQuery() in SoftDeletes::performDeleteOnModel() to match Model::performDeleteOnModel().

An example where the current behavior is incorrect:

$user = User::find(1);
$user->id = 2;
$user->delete();

This works without SoftDeletes but not with it.

@elnur-ibr
Copy link
Contributor Author

So should I create new pull request ? And update both SoftDeletes::performDeleteOnModel() and SoftDelete::runSoftDelete ?

@staudenmeir
Copy link
Contributor

Yes, please create a PR.

@driesvints
Copy link
Member

@staudenmeir thanks for verifying! :)

@driesvints
Copy link
Member

PR was merged.

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

No branches or pull requests

3 participants