Yii DAO and Validation

Is it possible to use Yii’s DAO and still have have Yii validate database fields that are declared as unique?

For example, consider a database table called “user” that has a user_id, user_name, and user_password. The user_name has to be unique. When using Yii’s Active Record declaring user_name as unique in the model’s rules like so:




public function rules()

{

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

  // will receive user inputs.

  return array(

    array('user_name, user_password', 'required'),

    array('user_name', 'unique'),

  );



and displaying the user_name text fields in a view like so:




  <div class="wide form">

    <?php echo $form->labelEx($model,'user_name'); ?>

    <?php echo $form->textField($model,'user_name'); ?>

    <?php echo $form->error($model,'user_name'); ?>

  </div>



will automatically validate the user_name attribute and report an error if the user enters a user_name that already exists in the user table.

Is it possible to achieve the same thing when using Yii’s DAO?

A second question: if using DAO, where should the DAO code be placed? For example, referring to the "user" example above, if I want to be able to add users, should I create something like addUser($user_name, $user_password) in the model, like so:




<?


class UserForm extends CFormModel

{

  public $user_name;

  public $user_password;


  public function rules()


  {

    return array(

      array('user_name, user_password', 'required'),

      //array('user_name', 'unique'),

      array('user_password', 'length', 'min'=>8, 'max'=>32),

    );

  }


  public function addUser($user_name, $user_password)

  {

    $connection = Yii::app()->db;

    $command = $connection->createCommand("CALL sp_CreateUser('$user_name', '$user_password')");

    $command->execute();    

  }       


}



and then call this from the controller?

Any help would be really appreciated.

Hi, I have the similar question. Have you found any solution? Thanks.

Haven’t experimented yet but I’m also curious if this is possible. And if so, are there any special tricks to make it work?

Correct me if I am wrong, but I don’t think validation is an feature only for ActiveRecord based Models (see http://www.yiiframework.com/doc/guide/1.1/en/form.model#declaring-validation-rules ).

Does it not work if you call validate() on your model before executing your DAO statement (and after assigning values to the attributes)?

Dear Scott ,

Could you please let us know if you have solution for these questions ? I am lucky I found there are people searching like me and I am unlucky I couldn’t find the answer ?

Thanks and Regards

Yii Fan ( Recent fan )

Hi Fan_of_Yii,

I had completely forgotten about this old post. I have since decided to study Yii’s implementation of ActiveRecord so that I can use all the cool Yii extensions (most of which require a CActiveDataProvider).

In regards to a solution, see Sisko’s response above. He is right - you can call the ‘validate()’ method to ensure model’s member vars adhere to the model’s rules. For example, using the UserForm model above, you could add this to your controller:




public function actionCreateUser()

{

  $model = new UserForm();

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

  {

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

    if (model->validate())

    {

      $model->addUser();      // Add the user to the database.

      $this->redirect(.....); // Redirect to another page.

    }

  }

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

}



Of course the UserForm::addUser method should be changed to:




public function addUser()

{

  $connection = Yii::app()->db;

  $command = $connection->createCommand("CALL sp_CreateUser('$this->user_name', '$this->user_password')");

  $command->execute();    

}  



(none of the above is tested, hope it makes sense).

As a side node, beware of MySQL stored procedures. For a long time LIMIT was unusable within a stored proc, making pagination an impossibility. I think it has been fixed recently: http://bugs.mysql.com/bug.php?id=11918

Thanks a lot Scott for your quick response .

I created a dao folder under protected folder and copying all my stuff there and imported it in main config file . Things are working pretty well .

I came from Oracle DBA and PL/SQL developer background and so tend to put most of the stuff in Stored procedures ( related to updates) to avoid more database calls .

Thanks again

Regards

Yii Fan ( Recent Fan)

Our large site is all DAO and we use you CModel validation methods for everything (Yii supplied and custom classes).