How do I update an active record with a beforeSave() in my model?

I have tried


public function beforeSave($insert){

	if (parent::beforeSave($insert)) {

		$directions = new Directions();

		$directions->product_directions = 'directions go here';

		$directions->save();

		$this->product_directionsID = Yii::$app->db->getLastInsertID();

			

		return true;

	}

}

and


public function beforeSave($insert){

	if (parent::beforeSave($insert)) {

		if(insert){

			$directions = new Directions();

			$directions->product_directions = 'directions go here';

			$directions->save();

			$this->product_directionsID = Yii::$app->db->getLastInsertID();

		}

			

		return true;

	}

}

in my model but update always fails. The page always goes back to the form and the data is not updated.

I thought that if $insert was false the beforeSave() function would not be called and an update() instead of an insert() would be done. The only way I can get an update to occur is if I comment out the beforeSave().

What am I missing here?

if $insert if true it means it’s a new record. If it’s false then it’s updating an existing record. You can see the docs here which also give the proper way to do this beforeSave() docs.

As a side note using the getLastInsertID() could return the wrong ID if you have multiple people using your application at the same time. I dont know if this works for you but you could do something like


public function beforeSave($insert) {

    //if parent beforeSave() failes dont allow saving

    if (!parent::beforeSave($insert)) {

        return false;

    }

    if ($insert) {

        //new record code here

        $directions = new Directions();

        $directions->product_directions = 'directions go here';

        //dont assign id unless directions save

        if ($direction->save()) {

            $this->product_directionsID = $directions->id;

        }

    } else {

        //updating record code here

    }

    //both inserting new and updating records code here

    //return true to allow saving

    return true;

}

Thanks. All working now.


public function beforeSave($insert){

    if (!parent::beforeSave($insert))

        return false;

    

    $directions = new Directions();

    

    if ($insert) {

        //Directions insert

        $directions->product_directions = 'directions go here';

	$directions->save(); //to avoid foreign key check failure

	$this->product_directionsID = Yii::$app->db->getLastInsertID();

	} else {

        //Directions update

	$directions->id = $this->product_directionsID;

	$directions->product_directions = 'updated directions go here';

    }

    return true;

}

Didn’t realize I still needed to actually set an update block of code.

For now I will use getLastInsertID() because


//dont assign id unless directions save

if ($direction->save()) {

   $this->product_directionsID = $directions->id;

}

triggers a Call to a member function save() on a non-object error. I’ll look into this later. This is an intranet application and the likely hood of multiple inserts is very low. I will want to clean it up.

Just FYI since you are creating a new instance of directions on save and update you will end up with a bunch of directions that don’t have products. On update of the product you should find the old directions record and update it.





public function beforeSave($insert){

    if (!parent::beforeSave($insert))

        return false;  

    if ($insert) {

        //Directions insert

	$directions = new Directions();

        $directions->product_directions = 'directions go here';

        $directions->save(); //to avoid foreign key check failure

        $this->product_directionsID = Yii::$app->db->getLastInsertID();

        } else {

        //Directions update

        $directions = Directions::findOne($this->product_directionsID);

        $directions->product_directions = 'updated directions go here';

        $directions->save();

    }

    return true;

}