CActiveModel question

I have a user registration form, to submit the user needs to fill out 2 fields that are NOT in the database (agreement and passwordTwo).

These are both active fields for my user registration form. Upon insertion to the database it seems to be failing (but validating), I believe it is because the agreement and passwordTwo fields don’t exist in the database and it is adding them into the sql command.

So my question is, how should i go about validation of these fields without screwing with yii’s generated sql string?

form


      <div class="simple">

        <?php echo CHtml::activeLabel($model,'password'); ?>

        <?php echo CHtml::activePasswordField($model,'password'); ?>

      </div>

      <div class="simple">

        <?php echo CHtml::activeLabel($model,'passwordTwo'); ?>

        <?php echo CHtml::activePasswordField($model,'passwordTwo'); ?>

      </div>

form


      <div class="action">

        <?php echo CHtml::activeLabel($model,'agreement'); ?>

        <?php echo CHtml::activeCheckBox($model,'agreement'); ?>

        <br/>

        <?php echo CHtml::submitButton('Register'); ?>

      </div>

User.php (model)




			// on register

			array('password', 'compare', 'compareAttribute'=>'passwordTwo','message'=>'Password field must match.', 'on'=>'register'),

			array('password', 'required', 'on'=>'register'),

			array('agreement', 'compare', 'compareValue'=>'1', 'message'=>'You must sign the agreement to continue.', 'on'=>'register'),

			array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd'), 'on'=>'register'),

This extra-fields will not figure in the SQL if you do not hardcode this :) The cause of this is Yii construct the SQL statement according to the appropriate table schema.

add tour extra fields to the safeAttributes method firstly.

It seems to me your code is correct. If agreements is not signed (i suppose it is signed only if $_POST[‘YourModelName[agreement]’] == 1?), you will receive the error messge you’ve defined in the models rules().

Either you can throw a glance at beforeValidate(), but anyway I think you do everything right. Eventually it worked for me fine at all times.

Cheerz.

You should provide the code of the controller where you try to save your model. The default option of the save method is that it validates the model before saveing with either ‘insert’ or ‘update’ scenario. That could be a problem too.

thanks for the replies, here is the register action in my controller (and more). it passes validation and runs save, but nothing is added to the db table.


  /**

   * render register page or create account

   */

  public function actionRegister()

  {

    $model = new User();

    $model->scenario = 'register';

    

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

    {

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

      

      if($model->validate())

      {

        $model->password = md5($model->password);

        $model->save();

        

        Yii::app()->user->setFlash('register',

                                   'Thank you for registering! You can ' . CHtml::link('login here', array('profile/login')) . '.');

      }

    }

    

    $model->password = '';

    $model->passwordTwo = '';

    $this->render('register', array('model'=>$model));

  }

safeAttributes and rules in full


	/**

	 * 

	 * 

	 */

    public function safeAttributes()

    {

        return array(

            'register'=>'name, email, phone, password, passwordTwo, addressOne, addressTwo, city, state, country, agreement, verifyCode',

            'admin'=>'name, email, phone, password, addressOne, addressTwo, city, state, country',

        );

    }

	

	/**

	 * Validation rules for the table

	 * 

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		return array(

			array('email', 'unique'),

			array('name, email, phone', 'required'),

			array('name','length','max'=>64),

			array('email','length','max'=>64),

			array('phone','length','max'=>16),

			array('password','length','max'=>256),

			array('addressOne','length','max'=>128),

			array('addressTwo','length','max'=>128),

			array('city','length','max'=>64),

			array('state','length','max'=>32),

			array('country','length','max'=>32),

			

			// on register

			array('password', 'compare', 'compareAttribute'=>'passwordTwo','message'=>'Password field must match.', 'on'=>'register'),

			array('password', 'required', 'on'=>'register'),

			array('agreement', 'compare', 'compareValue'=>'1', 'message'=>'You must sign the agreement to continue.', 'on'=>'register'),

			array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd'), 'on'=>'register'),

			

			// admin

			array('password', 'required', 'on'=>'admin'),

		);

	}

still haven’t figured out what is going on, even through watching the debugger. it executes the save but then never affects the db. hmmm.

save returns false <_<

Do you maybe use beforeSave() and forgot to return true at the end?

I figured out what was happening, partially due to your other post Mike. In the Register action I am changing the password to password = md5(password) after validate(). If you walk through the code with xdebug it actually validates again (in the parent class) right before it calls insert() or modify(), if this secondary validate fails it passes false all the way back up to save().

It fails validation because the password is md5 hashed and it tries to compare it to passwordTwo which is not hashed in the code i posted.

SOLUTION: Implement hashing in onBeforeSave() :lol:

thanks for the help

You could eben get around that onBeforeSave() by putting the compare validator into its own scenario e.g. ‘register’. Then if you don’t set this scenario on your model object the rule won’t apply.