beforeSave not being called


(Gposse) #1

Hi,

I addedd the protected function beforeSave to a model class in order to fill some fields that are not user input.

The Controller is calling the ‘save’ method but beforeSave is not being called. I even tried to put an exception as the first line of the beforeSave function but nothing happens.

Thanks in advance.


(Arekandrei) #2

Can you show a code of your model & controller? beforeSave() is always called when a record is being inserted/updated.


(Junior) #3

But in Yii’s cookbook there is something like




public function beforeSave() {

    if ($this->isNewRecord)

        $this->created = new CDbExpression('NOW()');

    else

        $this->modified = new CDbExpression('NOW()');

 

    return parent::beforeSave();

}



Note that the function is declared as public and there is a call to the parent’s beforeSave() method also

This is working around here, have you tried this way?

regards


(Arekandrei) #4

I always declare all after/before functions as "protected", because they are protected in the parent class and should not be called outside it (or any descendant).


(Live Webscore) #5

Did you return true at the end of your function?


(Arekandrei) #6

I don’t understand why people always say to return true in the end of “before” methods. If you’ll return true, an event “onBefore…” won’t be called! You should always put “return parent::beforeSave()” in the end of redefined beforeSave() method (same for other “before” methods, and without “return” for “after” methods).

And I don’t think it’s the problem there, since man said he put Exception at the first line…

Sorry if it is "offtop".


(Live Webscore) #7

True. I was not sure if the user has included "return parent::beforeSave()" as the user did not show any code. Sorry if my comment does not help


(Gposse) #8

Here is the code:

protected function beforeSave()

{

if(parent::beforeSave())

{

  if($this->isNewRecord)


  {


     $this->create_time=time();


  }


  return true;

}

else

  return false;

}

THe controller function is the following:

public function actionCreate()

{

$model=new Group;

if(isset($_POST[‘Group’]))

{

  $model->attributes=$_POST['Group'];


  if(!$model->save())


     throw new CHttpException(400,Yii::t('base','Save failed.'));


  $this->redirect(array('view','id'=>$model->id));

}

}

The funny thing is that if add the following line:

throw new CHttpException(400,‘Hello’);

as the first line in the beforeSave function, it is never called (so beforeSave is never called).

If I add the following line:

$model->create_time=time();

just before calling the save function in the controller, then the exception is thrown (so beforeSave is called).

I find no logical explanation for this behavior.


(O Rijkers) #9

Your code looks alright.

Do you have any rule set on the create_time attribute? (maybe post your rules() method, too.

b.t.w. if you enter code, please use the ‘[ code]’ and ‘[ / code]’ tags (without the spaces in it), that way it will be displayed nicely.


(Ft07) #10

If validation doen’t pass you would not reach the (protected) beforeSave()method. BTW remember to call parent or the onBeforeSave event would not fire.

There is also a (public) beforeSave() event handler, e.g in CActiveRecordBehavior.

/Tommy


(Gposse) #11

I removed create_time from the required rule. Now it works. Validation was not passing.

Thanks to everybody.