Behaviors

Hi All,

I am unable to resolve this issue or think why it was growing wrong.

I have a model extending CModel in which i am attaching a behavior which has been extended from CModelBehavior.

Here is my code…

Model:




class SoapModel extends CModel

{

 public function behaviors()

    {

        yii::log("behavior ***************\n\n\n", 'info');

        return array(

                'vllBehavior' => array(

                                  'class' => 'application.modules.AlcatelSam.models.VllService'

                    ),

   			);


}//end behaviors()

}//end class



Behavior:




class VllService extends CModelBehavior

{


public function foo()[/indent][indent]

{

yii::log("behavior ***************\n\n\n", 'info');[/indent][/indent][indent]


}//end foo()


}//end class



After i create my model instance and call $modelObj->foo() i get object not defined error.

More over i don’t see any trace messages i have put in my behaviors() function.

When i explicitly attach the behavior by doing

$modelObj->attachBehavior(‘bar’, new VllService());

this works well.

I am using yii-1.1.3 appreciate any clues or any debugging ways to resolve it.

Thanks,

Jai

Hi Jai,

CModelBehavior is used to extend specific model methods: afterConstruct, afterValidate, and beforeValidate. If you need higher level methds (ex your foo() method) you should extend your behavior from CBehavior.

Try that and let me know how it goes.

Matt

I have used you code and it works as expected. Please check the path to the class is correct.

Matt

A question about my own posting. Is the quote below correct or is it ok to add extra method to a specialized class such as CModelBehavior? Usually, when I need to extend a model class, and don’t need the functionality of after/beforeValidate(), I extend from CBehavior.

Thanks,

Matt

If you don’t need that functionality there is no need to extend CModelBehavior, adding this functionality to a class that extends CModelBehavior is not wrong (cause it’s extending CBehavior anyway) , but its totally unnecessary.

I have resolved this issue after browsing the source code of CActiveRecord.php and CModel.php.

In CActiveRecord constructor it explicitly calls attachBehaviors() and afterConstruct()





/**

 	* Constructor.

 	* @param string $scenario scenario name. See {@link CModel::scenario} for more details about this parameter.

 	*/

    public function __construct($scenario='insert')

    {

        /** few lines of constructor code are not shown here **/


        $this->attachBehaviors($this->behaviors());

        $this->afterConstruct();

    }




This was missing in CModel.php. So when i added the following lines to my constructor it worked perfectly.





class ServiceRed extends Service

{


    public function  __construct()

    {

        $this->attachBehaviors($this->behaviors());

        $this->afterConstruct();

    }


   

    public function behaviors()

    {

        return array(

                'vllBehavior' => array('class' => 'VllService'),

           	);


    }//end behaviors()


}//end class



I am still not sure why the above piece of code was missing in CModel.php.

@[color="#2B3730"]waterlooma: [/color][color="#2B3730"]Yes i needed the afterConstruct() and beforeValidate() events so i was using CModelBehavior. [/color]

[color="#2B3730"]Thanks,[/color]

[color="#2B3730"]Jai [/color]

Seems you found a bug. Indeed CModel.php contains behaviors() but the constructor code really is missing. No one found this so far probably because it’s there in CFormModel and CActiveRecord’s constructor.