GithubHelp home page GithubHelp logo

yii2tech / ar-softdelete Goto Github PK

View Code? Open in Web Editor NEW
207.0 18.0 47.0 61 KB

Soft delete behavior for ActiveRecord

License: Other

PHP 100.00%
yii yii2 yii2-extension soft-deletes soft-delete activerecord

ar-softdelete's People

Contributors

klimov-paul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ar-softdelete's Issues

Optimistic lock problem

Optimistic lock logic is not taken into account when soft delete/restore

my quick fix
replace in delete/restore internal methods

$result = $this->owner->updateAttributes($attributes);

with

$this->owner->setAttributes($attributes, false);
$result = $this->owner->update(false, array_keys($attributes));

leftjoin alias error

$query = xx::find()->alias('t1')->select('t1.aa')
->where(['>', 't2.aa', 0])
->leftJoin(yy::tableName() . ' t2', 't1.aa=t2.aa');
$deals = $query->orderBy('t2.aa desc')->limit(10)->asArray()->all();
error:
Column not found: 1054 Unknown column 'xx.is_delete' in 'where clause'
The SQL being executed was: SELECT t1.aa FROM xx t1 LEFT JOIN yy t2 ON t1.aa=t2.aa WHERE (t2.aa > 0) AND (xx.is_delete=0)

suggestion for query deleted

What steps will reproduce the problem?

model :

    /**
     * @return \yii\db\ActiveQuery|SoftDeleteQueryBehavior
     */
    public static function find(){
        // $query = parent::find();
        $query->attachBehavior('softDelete', SoftDeleteQueryBehavior::className());
        return $query;
    }

controller :

        $query = TappsPrincipalHolding::find()
             ->notDeleted()->one();

What is the expected result?

iam has alot of query for it, so how if remove notDeleted in controller, better if not used it. Cz i'll not need it in App, just need in database if really needed..

suggestion :

$query = parent::find()->andWhere(['=', 'isDeleted', 0]);

is it right ?
or it should works without my changes ?
Thanks for pay attention..

Boolean vs Timestamp

Would it not make sense to use a unix timestamp to indicate deletion as opposed to a simple boolean?

It is certainly important to know when a record was deleted, not just whether it was. It could both be done with one column by storing unix timestamps instead of booleans. A set value means that the record was deleted AND it also tells you when. The column being NULL means the record has not been deleted. Furthermore this could be done consistently with TimestampBehavior by calling the attribute "deleted_at".

The only (and perhaps negligible) downside is the possibility of slightly higher storage requirement (using INT instead of BIT).

At the very least this could be a configurable option of SoftDelete.

getting yii\base\UnknownPropertyException about "model::isDeleted

I am using softdelete in our model, when we go for delete then we get this error yii\base\UnknownPropertyException .

Used code in model is
use yii\base\ModelEvent;
use yii2tech\ar\softdelete\SoftDeleteBehavior;
.......
{
public function behaviors()
{
return [
'softDeleteBehavior' => [
'class' => SoftDeleteBehavior::className(),
'softDeleteAttributeValues' => [
'isDeleted' => true
],
],
];
}
.......
}

Soft Delete All not given

I have inserted the behaviour in the active model now i need for soft delete all based on certain condition I cannot as there is no option for that

Want some kind of function like SoftDeleteAll("condition") which will be same as delete all

I had to wirite an update all like where i set all isdelete flag as 1
I had to use it in a relational model

beforeSoftDelete() is wrongly documented

This code wont work, because the method softDeleteInternal() will rewrite the values of the attributes during the execution of lines https://github.com/yii2tech/ar-softdelete/blob/master/SoftDeleteBehavior.php#L179-L185 which will only update the attributes defined in the softDeleteAttributeValues property using the values defined there.

   public function beforeSoftDelete()
    {
        $this->deletedAt = time(); // log the deletion date
        return true;
    }

Is the documented example which doesn't work.

"restore" records - Call to a member function restore() on null

When I restore the record I get an error,

Call to a member function restore () on null

which is probably related to this. By using:

public static function find (){          return parent: find () -> where (['isDeleted' => false]);  }

for the record deleted
$item = Item :: findOne ($ id);
$item will be null
$item->restore(); // restore record
This way, you can not restore marked items as deleted

Instalation via Composer fail, using php version 7.3.7

What steps will reproduce the problem?

php composer.phar require --prefer-dist yii2tech/ar-softdelete

What is the expected result?

Instalation success

What do you get instead?

Using version ^1.0 for yii2tech/ar-softdelete
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - mpdf/mpdf 7.0.2 requires php ^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 -> your PHP version (7.3.7) does not satisfy that requirement.
    - mpdf/mpdf 7.0.2 requires php ^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 -> your PHP version (7.3.7) does not satisfy that requirement.
    - mpdf/mpdf 7.0.2 requires php ^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 -> your PHP version (7.3.7) does not satisfy that requirement.
    - Installation request for mpdf/mpdf (locked at 7.0.2) -> satisfiable by mpdf/mpdf[7.0.2].

Additional info

| Q                     | A
| --------------------- | ---
| This Package Version  | ^1.0.0
| Yii Framework Version | 2.0.0
| PHP version           |  7.3.7
| Operating system      | Ubuntu 18.04

$model->delete() returns false when replaceRegularDelete => true

I know you have to stop a hard delete in the beforeDelete event. Which eventually returns false to the delete() function. Is there a proper way to get the delete function to not return false?

public function behaviors()
{
    return [
        'softDeleteBehavior' => [
            'class' => SoftDeleteBehavior::className(),
            'softDeleteAttributeValues' => [
                'whenDeleted' => new Expression('NOW()')
            ],
            'restoreAttributeValues' => [
                'whenDeleted' => null
            ],
            'replaceRegularDelete' => true
        ],
    ];
}

What I have so far was override the deleteAll static function in the model so that the ActiveRecord deleteInternal function would not hard delete the record

public static function deleteAll($condition = '', $params = [])
{
    return 1;
}

And remove the $event->isValid = false; line in the beforeDelete event function from SoftDeleteBehavior so that $model->delete() would eventually return true

public function beforeDelete($event)
{
    if (!$this->isDeleteAllowed()) {
        $this->softDeleteInternal();
//      $event->isValid = false;
    }
}

soft delete on delete cascade foreign key

What steps will reproduce the problem?

CREATE TABLE `Customer`
(
   `id` integer NOT NULL AUTO_INCREMENT,
   `name` varchar(64) NOT NULL,
   `address` varchar(64) NOT NULL,
   `phone` varchar(20) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE InnoDB;

CREATE TABLE `Purchase`
(
   `id` integer NOT NULL AUTO_INCREMENT,
   `customerId` integer NOT NULL,
   `itemId` integer NOT NULL,
   `amount` integer NOT NULL,
    PRIMARY KEY (`id`)
    FOREIGN KEY (`customerId`) REFERENCES `Customer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY (`itemId`) REFERENCES `Item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
) ENGINE InnoDB;

I have mysql table like this with foreign key to another table and I set ON DELETE CASCADE

What is the expected result?

if I perform soft delete record on table Customer, the contain record on Purchase table should mark as soft deleted

What do you get instead?

when I 'soft deleted' record on table Customer, the contain record on Purchase table not mark as soft deleted.

I tried both command, softDelete and safeDelete, it still just mark soft deleted on table Customer, not on Purchase table..

Additional info

Q A
This Package Version 1.0.4
Yii Framework Version 2.0.38
PHP version 7.4.9
Operating system Windows 10 build 2004

Error using soft delete - Unknown Property

Unknown Property – yii\base\UnknownPropertyException
Setting unknown property: app\models\Employee::isDeleted

To use soft delete should i insert the isDeleted attribute into the database employee table?

composer.json problem

I get a problem when I want to update yii2 version to 2.0.14.1 hotfix version

Problem 1
- The requested package yiisoft/yii2 2.0.14.1 exists as yiisoft/yii2[2.0.0, 2.0.0-alpha, 2.0.0-beta, 2.0.0-rc, 2.0.1, 2.0.10, 2.0.11, 2.0.11.1, 2.0.11.2, 2. 0.12, 2.0.13, 2.0.13.1, 2.0.14, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.7, 2.0.8, 2.0.9, 2.1.x-dev, dev-master, 2.0.x-dev] but these are rejected by your constra int.
Problem 2
- yii2tech/ar-softdelete 1.0.1 requires yiisoft/yii2 * -> satisfiable by yii soft/yii2[2.0.0, 2.0.0-alpha, 2.0.0-beta, 2.0.0-rc, 2.0.1, 2.0.10, 2.0.11, 2.0.1 1.1, 2.0.11.2, 2.0.12, 2.0.13, 2.0.13.1, 2.0.14, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0 .6, 2.0.7, 2.0.8, 2.0.9, 2.1.x-dev, dev-master, 2.0.x-dev] but these conflict wi th your requirements or minimum-stability.
- yii2tech/ar-softdelete 1.0.1 requires yiisoft/yii2 * -> satisfiable by yii soft/yii2[2.0.0, 2.0.0-alpha, 2.0.0-beta, 2.0.0-rc, 2.0.1, 2.0.10, 2.0.11, 2.0.1 1.1, 2.0.11.2, 2.0.12, 2.0.13, 2.0.13.1, 2.0.14, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0 .6, 2.0.7, 2.0.8, 2.0.9, 2.1.x-dev, dev-master, 2.0.x-dev] but these conflict wi th your requirements or minimum-stability.
- Installation request for yii2tech/ar-softdelete ^1.0.1 -> satisfiable by y ii2tech/ar-softdelete[1.0.1].

alias problem.

hi. i am test sample find:
Contacts::find() ->alias('c') ->joinWith(['sexuality' => function (\yii\db\ActiveQuery $query) { $query->alias('s'); }])->createCommand()->getSql();
query result:
SELECT "c".* FROM "contacts" "c" LEFT JOIN "domain" "s" ON ("c"."sexuality_id" = "s"."id") AND("domain"."deleted_at" IS NULL) WHERE "contacts"."deleted_at" IS NULL
alias does not apply in query.

Enhancements, questions

  1. Существует ли возможность заставить редакторы видеть новые методы? (Конкретно PHPStorm)
  2. Можно ли добавить метод isDeleted(), который будет возвращать реальный статус, в зависимости от логики при инициализации? В текущей реализации необходимо каждый раз прописывать логику (например $item->isDeleted === null ? do_something : do_another).
  3. Чаще всего, когда применяется этот behavior, то нужно фильтровать данные таким образом, чтобы исключить удаленные записи из выборки. Можно ли автоматически добавлять условие в find() на фильтрацию? Только тут нельзя забывать про возможность добавления
    public static function find()
    {
        return new ItemQuery(get_called_class());
    }

При этом остается необходимость выборки удаленных записей. В этом плане есть хорошие реализации у Laravel, RoR, Sequelize (nodejs).

  1. Может ли этот behavior стать частью ядра Yii? Это решило бы некоторые проблемы, описанные выше.

Issues

1) Issue 1:

My model:

class Expense extends ActiveRecord
{
...

    public static function find()
    {
        return parent::find()->where(['is_deleted' => 0]);
    }

...
}

My search model:

    public function search($params)
    {
        $query = Expense::find();
        $query->where(['expense.company_id' => Yii::$app->user->identity->company_id]);

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $this->load($params);

        if (!$this->validate()) {
            return $dataProvider;
        }
}

My Controller:

        $searchModel = new ExpenseSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

The behavior stop working because of this code in my search model:

$query->where(['expense.company_id' => Yii::$app->user->identity->company_id]);

2) Issue 2:

The following code doesn't work as well:

            return Notification::find()
                ->with(['user'])
                ->where(['to_user_id' => Yii::$app->user->id])
                ->orderBy(['id' => SORT_DESC])
                ->limit(Notification::LIMIT_PER_PAGE)
                ->all();

3) Issue 3:

It's impossible to use join when two tables have the is_deleted field.

Error on join

Integrity constraint violation – yii\db\IntegrityException
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'isDeleted' in where clause is ambiguous

How to use AND (table.isDeleted <> 1) for default?

Attributes set in beforeSoftDelete will not be saved , $attributes should init from $this->owner ?

    protected function softDeleteInternal()
    {
        $result = false;
        if ($this->beforeSoftDelete()) {
            //$attributes = [];
            **$attributes = $this->owner->getAttributes();**
            foreach ($this->softDeleteAttributeValues as $attribute => $value) {
                if (!is_scalar($value) && is_callable($value)) {
                    $value = call_user_func($value, $this->owner);
                }
                $attributes[$attribute] = $value;
            }
            $result = $this->owner->updateAttributes($attributes);
            $this->afterSoftDelete();
        }
        return $result;
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.