Yii Framework Forum: [Solved]Is it possible to get old value in beforeSave() - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

[Solved]Is it possible to get old value in beforeSave() Rate Topic: -----

#1 User is offline   junxiong 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 543
  • Joined: 21-June 10

Posted 25 August 2010 - 11:10 PM

in the CActiveRecord class, I create a beforeSave() function. In here I want to get the old value of the model. Is there any way to do it? thanks before
“The most likely way for the world to be destroyed, most experts argue, is by accident. That’s where we come in; we’re computer professionals. We cause accidents.” - Nathaniel Borenstein

Yii Playground : Collaborative demo apps. You can join to improve it too!
My Team's Blog: In Indonesian.
0

#2 User is offline   soso 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 45
  • Joined: 24-February 10

Posted 26 August 2010 - 01:25 AM

View Postjunxiong, on 25 August 2010 - 11:10 PM, said:

in the CActiveRecord class, I create a beforeSave() function. In here I want to get the old value of the model. Is there any way to do it? thanks before


You can load it from the database, using another instance of the AR. Your you could clone your original instance before modifying its fields.
1

#3 User is offline   phreak 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 19-February 09

Posted 26 August 2010 - 01:59 AM

View Postsoso, on 26 August 2010 - 01:25 AM, said:

You can load it from the database, using another instance of the AR. Your you could clone your original instance before modifying its fields.

I have exactly the same logic for tracking changes to AR.

            
public function beforeSave()
    {
        $this->changesText = '';
        $curr = self::findByPk($this->id);
        if($curr)
        {
            if($curr->name != $this->name)
                $this->changesText .= "Change name to \"{$this->name}\".";
            if($curr->region_id != $this->region_id)
                $this->changesText .= "Change region to \"{$this->region->name}\".";  
..............

0

#4 User is offline   junxiong 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 543
  • Joined: 21-June 10

Posted 26 August 2010 - 08:47 AM

View Postphreak, on 26 August 2010 - 01:59 AM, said:

I have exactly the same logic for tracking changes to AR.

            
public function beforeSave()
    {
        $this->changesText = '';
        $curr = self::findByPk($this->id);
        if($curr)
        {
            if($curr->name != $this->name)
                $this->changesText .= "Change name to \"{$this->name}\".";
            if($curr->region_id != $this->region_id)
                $this->changesText .= "Change region to \"{$this->region->name}\".";  
..............



I see. I've got your logic..
Thank you very much, phreak and soso :)
“The most likely way for the world to be destroyed, most experts argue, is by accident. That’s where we come in; we’re computer professionals. We cause accidents.” - Nathaniel Borenstein

Yii Playground : Collaborative demo apps. You can join to improve it too!
My Team's Blog: In Indonesian.
0

#5 User is offline   Thomas Jensen 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 150
  • Joined: 01-August 09

Posted 25 April 2011 - 02:45 AM

In my opinion, this is bad practice, as the model you load from DB really should be the same as the one you are currently in. It's just because Yii haven't implemented the Identity Map pattern yet: http://en.wikipedia....i/Identity_map.
0

#6 User is offline   AirborneAgain 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 28-November 11

Posted 29 March 2012 - 01:27 PM

I know this is an old thread, but I wanted to note how I am doing this - for people that are still searching like I was. I, like most of us, have a base class that I use for all my models that extends CActiveRecord. In that class, I have a get/set for OldAttributes. In the init, I hook into the OnAfterFind event, and add a line of code that populates my old attributes. It's simple, yet effective, and has pretty low overhead - with no second database query. Here's a simplified version of the code I'm using:

class MyModel extends CActiveRecord
{
    private $_oldAttributes = array();
    public function setOldAttributes($value)
    {
        $this->_oldAttributes = $value;
    }
    public function getOldAttributes()
    {
        return $this->_oldAttributes;
    }

    public function init()
    {
        $this->attachEventHandler("onAfterFind", function ($event)
        {
            $event->sender->OldAttributes = $event->sender->Attributes;
        }
    }
}


From there, I have access via:

// Inside the model itself
$OldColumnInfo = $this->OldAttributes['ColumnName'];

// Via an instance
$OldColumnInfo = $MyModelInstance->OldAttributes['ColumnName'];

4

#7 User is offline   Fabián 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 30-September 12

Posted 29 December 2012 - 03:31 PM

View PostAirborneAgain, on 29 March 2012 - 01:27 PM, said:

I know this is an old thread, but I wanted to note how I am doing this - for people that are still searching like I was. I, like most of us, have a base class that I use for all my models that extends CActiveRecord. In that class, I have a get/set for OldAttributes. In the init, I hook into the OnAfterFind event, and add a line of code that populates my old attributes. It's simple, yet effective, and has pretty low overhead - with no second database query. Here's a simplified version of the code I'm using:

class MyModel extends CActiveRecord
{
    private $_oldAttributes = array();
    public function setOldAttributes($value)
    {
        $this->_oldAttributes = $value;
    }
    public function getOldAttributes()
    {
        return $this->_oldAttributes;
    }

    public function init()
    {
        $this->attachEventHandler("onAfterFind", function ($event)
        {
            $event->sender->OldAttributes = $event->sender->Attributes;
        }
    }
}


From there, I have access via:

// Inside the model itself
$OldColumnInfo = $this->OldAttributes['ColumnName'];

// Via an instance
$OldColumnInfo = $MyModelInstance->OldAttributes['ColumnName'];




Thanks AirborneAgain.

I think using "afterFind" event is a very elegant solution.
0

#8 User is offline   Boaz 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 371
  • Joined: 23-January 11

Posted 30 December 2012 - 10:22 AM

View PostFabián, on 29 December 2012 - 03:31 PM, said:

Thanks AirborneAgain.

I think using "afterFind" event is a very elegant solution.


This is exactly what I do in a base class all my AR models are extending. I've released it as an extension - PcBaseArModel. Perhaps it will be useful for you to examine it. See there isAttributeDirty().
Therapeutic PHP sessions My LinkedIn Profile
0

#9 User is offline   seenivasan 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 620
  • Joined: 17-June 12
  • Location:Chennai,TamilNadu,India.

Posted 30 December 2012 - 12:02 PM

Dear Friends

We can do the things in the following way.

class User extends CActiveRecord
{  
    public $oldRecord;

    public function afterFind()
    {
		$this->oldRecord=clone $this;
                return parent::afterFind();	
    }


Now We can access the old attributes in beforeSave method.
$this->oldRecord->password;


I am not sure whether cloning the objects in such a way is advisable.
2

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users