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

Reset dirty attributes after afterSave #13472

Closed
ztdan4ik opened this issue Jan 30, 2017 · 8 comments
Closed

Reset dirty attributes after afterSave #13472

ztdan4ik opened this issue Jan 30, 2017 · 8 comments

Comments

@ztdan4ik
Copy link

ztdan4ik commented Jan 30, 2017

In 2014 @cebe have commit changes for this issue #2892 f439520
So, that _oldAttributes can be used in afterSave() method
But now, as I can see it's not working and according framework source _oldAttributes reset before afterSave()

$changedAttributes = [];

@cebe
Copy link
Member

cebe commented Jan 30, 2017

what exactly is the problem?

@ztdan4ik
Copy link
Author

ztdan4ik commented Jan 30, 2017

For example:

class Customer extends ActiveRecord
{
    /**
     * @return string the name of the table associated with this ActiveRecord class.
     */
    public static function tableName()
    {
        return 'tbl_customer';
    }

    /**
     * @inheritdoc
     */
    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);

        if ($this->isAttributeChanged('status')) {
            die('PROFIT!');
        }
        die('FU** THIS SHIT!');
    }
}

In afterSave $this->isAttributeChanged('status') return false, even if status has changed.

@cebe
Copy link
Member

cebe commented Jan 30, 2017

you can use array_key_exists('status', $changedAttributes). That is the reason this parameter is provided.

@cebe cebe closed this as completed Jan 30, 2017
@ztdan4ik
Copy link
Author

ztdan4ik commented Jan 30, 2017

Ok, that's good. Thanks, @cebe ! But this solution is useless in behavior for EVENT_AFTER_INSERT and EVENT_AFTER_UPDATE

For example:

class TimeLineCommand extends Behavior
{

    public function events()
    {
        return [
            ActiveRecord::EVENT_AFTER_INSERT => 'afterSave',
            ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave',
        ];
    }

    public function afterSave($event)
    {
        if ($this->owner->isAttributeChanged('status')) {
            die('PROFIT!');
        }
        die('FU** THIS SH**!');
    }

}

Here is no $changedAttributes :(

@cebe
Copy link
Member

cebe commented Jan 30, 2017

@ztdan4ik
Copy link
Author

ztdan4ik commented Jan 30, 2017

@cube You are my hero!
Sorry for disturb

@vaso2
Copy link

vaso2 commented Oct 20, 2018

Hi there! Any plans for refactoring this behavior? In my case, changedAttributes usage need a lot of duplicated code, checks etc.
For example, I need to send an email about some connected data, when at least one field changes (example: from_time - to_time pair):
lots of complexity just to check if there is at least one changed attribute, then again for every field when trying to determine previous value ($this->getOldAttribute("field") returns current one if unchanged, $event->changedAttributes is array, so when key is not set...)
So, while current design choice seems strange to me, maybe It's just too rare use case?
Thanks for making this awesome framework even better!

@samdark
Copy link
Member

samdark commented Oct 22, 2018

Not in Yii 2.0 but could be done in https://github.com/yiisoft/active-record. Please post your suggestions in an issue there. Thanks.

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

4 participants