Yii not saving a not required field

ActiveRecord is not saving a value on update action.

The field not being saved is ‘id_empresa’ and is a foreign key of ‘Empleado’ model. This is my code:

Model (Empleado):


	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('estado, primer_nombre, primer_apellido, foto_bool, sex', 'required'),

			array('estado', 'numerical', 'integerOnly'=>true),

			array('primer_nombre, segundo_nombre, tercer_nombre, primer_apellido, segundo_apellido, casada_apellido, codigo, identificacion', 'length', 'max'=>256),

			array('foto_bool', 'length', 'max'=>5),

			array('sex', 'length', 'max'=>1),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('id_empleado, estado, primer_nombre, segundo_nombre, tercer_nombre, primer_apellido, segundo_apellido, casada_apellido, foto_bool, foto, sex, codigo, identificacion', 'safe', 'on'=>'search'),

		);

	}

Controller:


	public function actionUpdate($id)

	{

		$model=$this->loadModel($id);


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Empleado']))

		{

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

			if($model->save())

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

		}


		$this->render('update',array(

			'model'=>$model,

		));

	}

Form (relevant part only):

[html] <div class="row">

	&lt;?php echo &#036;form-&gt;labelEx(&#036;model,'empresa'); ?&gt;


	&lt;?php echo &#036;form-&gt;dropDownList(&#036;model,'id_empresa', CHtml::listData(Empresa::model()-&gt;findAll(), 'id_empresa', 'nombre_empresa')); ?&gt;


	&lt;?php echo &#036;form-&gt;error(&#036;model,'empresa'); ?&gt;


&lt;/div&gt; [/html]

But when I make theese changes to the Model then it works:


- array('estado, primer_nombre, primer_apellido, foto_bool, sex', 'required'),

+ array('estado, primer_nombre, primer_apellido, foto_bool, sex, id_empresa', 'required'), 


- array('id_empleado, estado, primer_nombre, segundo_nombre, tercer_nombre, primer_apellido, segundo_apellido, casada_apellido, foto_bool, foto, sex, codigo, identificacion', 'safe', 'on'=>'search'),

+ array('id_empleado, estado, primer_nombre, segundo_nombre, tercer_nombre, primer_apellido, segundo_apellido, casada_apellido, foto_bool, foto, sex, codigo, identificacion, id_empresa', 'safe', 'on'=>'search'),

WHY?!?!

id_empresa must be in any rule of the model’s scenario to validate, if you dont have any rule to match it add




array('id_empresa','safe')



but from what I see it should be


array('id_empresa','numerical' 'integerOnly'=>true);

turn on application log, then you see why it not saving, first what can be that your attribute is not specified as safe attribute or other type of attribute in your scenario, so it won’t be passed to your model and it wont be saved.

Thank you very much Gustavo!

Where can I find more info about the concept of ‘safe’ and ‘unsafe’ attribute? I’ve read this http://www.yiiframework.com/doc/guide/1.1/en/form.model#securing-attribute-assignments but still is not clear. When should I prefer ‘unsafe’ instead of ‘safe’?

Is simple: if on a model there is a validator, it is considered as safe, it means that will be massively assigned by


$model->attributes= $_POST['modelClassName']

Should be safe all and only the attributes that will be edited by users. The idea of using validators comes because if a field should be validate, it means that has been edited by a user.

There can be field that will be edited by users, but wich can have any value, and even can be empty. In this case we must explain to the application that this filed should be massively assigned, that’s why exist the safe validator, wich don’t do any validation, just set the field as safe.

This is the framework philospy, I like this approach very much, while someone else, like Mike, don’t like it… anyway Yii works like that

Thanks Zaccaria, but still, in which case should I declare some attribute as ‘unsafe’?

when the user will never fill it, the attribute will be assigned by the system / application

From what I see, it is the same as if don’t declare it

http://www.yiiframework.com/doc/api/1.1/CUnsafeValidator

http://www.yiiframework.com/doc/api/1.1/CSafeValidator

Thanks!

Usually is not needed to explicit mark an attribute as unsafe, if there is no validator on it is unsafe.

It is the philosopy of "allow what is permitted".

In some case can be more confortable in writing complex rules with complex scenarion to make safe some field and, for certain scenarios, make unsafe.

This is the philosophy of "deny what is forbidden", that is much less safer than the previous one.

If you are not in a complex case with many complex scenario, you should not need the unsafe validator.

For the sake of completeness I found a use case of ‘unsafe’ keyword: http://www.yiiframework.com/wiki/2/#c3137