2013-06-20 38 views
2

ChangeEmailForm延伸CFormModel为什么CFormModel :: validate需要在tableName中?

<?php 

/** 
* LoginForm class. 
* LoginForm is the data structure for keeping 
* user login form data. It is used by the 'login' action of 'SiteController'. 
*/ 
class ChangeEmailForm extends CFormModel 
{ 
    public $newemail; 
    public $password; 

    /** 
    * Declares the validation rules. 
    * The rules state that username and password are required, 
    * and password needs to be authenticated. 
    */ 
    public function rules() 
    { 
     return array(
      array('newemail, password', 'required'), 
      array('newemail', 'email'), 
      array('newemail', 'unique', 'attributeName' => 'User.email'), 
      array('password', 'authenticate') 
     ); 
    } 

    /** 
    * Declares attribute labels. 
    */ 
    public function attributeLabels() 
    { 
     return array(
      'newemail' => 'Новый Email-адрес', 
      'password' => 'Пароль учетной записи' 
     ); 
    } 

    /** 
    * Authenticates the password. 
    * This is the 'authenticate' validator as declared in rules(). 
    */ 
    public function authenticate($attribute, $params) 
    { 
     if (!$this->hasErrors()) { 
      $user = User::model()->findByAttributes(array(
       'password' => $this->password, 
       'id' => Yii::app()->user->id 
      )); 
      if ($user === null) 
       $this->addError('password', 'Неверный пароль учетной записи.'); 
     } 
    } 
} 

而且我在ProfileController了以下行动:

public function actionSettings() 
{ 
    $profile = $this->loadModel(Yii::app()->user->id); 
    $model = new ChangeEmailForm; 

    // if it is ajax validation request 
    if(isset($_POST['ajax']) && $_POST['ajax']==='change-email-form') 
    { 
     echo CActiveForm::validate($model); 
     Yii::app()->end(); 
    } 

    // collect user input data 
    if(isset($_POST['ChangeEmailForm'])) 
    { 
     $model->attributes=$_POST['ChangeEmailForm']; 
         // validate user input and redirect to the previous page if valid 
         if($model->validate()) { 
     $this->redirect('/'); 
     } 

    } 

    $this->render('settings',array(
     'model'=>$model, 
     'profile'=>$profile, 
    )); 
} 

,并查看:

<?php 
/* @var $this ProfileController */ 
/* @var $model ChangeEmailForm */ 
/* @var $profile User */ 
/* @var $form CActiveForm */ 

$this->breadcrumbs=array(
    'Учетная запись', 
); 
?> 

<h1>Настройки учетной записи</h1> 

<h2>Смена email-адреса</h2> 
<div class="form-register"> 

    <?php $form=$this->beginWidget('CActiveForm', array(
     'id'=>'change-email-form', 
     'enableAjaxValidation'=>true, 
    )); ?> 

    <div class="row"> 
     <div class="col col-label"><?php echo $form->labelEx($model,'newemail', array('class'=>'label1')); ?></div> 
     <div class="col col-input"><?php echo $form->textField($model,'newemail',array('size'=>32,'maxlength'=>64, 'class'=>'input1')); ?></div> 
     <div class="col col-error"><?php echo $form->error($model,'newemail'); ?></div> 
    </div> 

    <div class="row"> 
     <div class="col col-label"><?php echo $form->labelEx($model,'password', array('class'=>'label1')); ?></div> 
     <div class="col col-input"><?php echo $form->passwordField($model,'password',array('size'=>32,'maxlength'=>128, 'class'=>'input1')); ?></div> 
     <div class="col col-error"><?php echo $form->error($model,'password'); ?></div> 
    </div> 

    <div class="row buttons"> 
     <div class="col col-label"></div> 
     <div class="col col-input"><?php echo CHtml::submitButton('Сменить пароль', array('class'=>'submit1')); ?></div> 
    </div> 

    <?php $this->endWidget(); ?> 

</div><!-- form --> 

问题:递交表格后,我的应用程序抛出一个例外:ChangeEmailForm及其行为没有有一个名为“tableName”的方法或闭包。

问题:为什么CFormModel会抛出此异常?为什么一切工作在LoginForm的例子SiteController

附:对不起,我是Yii的初学者。

+0

你正在运行'actionSettings()'我假设? – Pitchinnate

+0

是的,actionSettings() – frops

+0

最好在SO上发布与问题相关的代码片段,但不要在离线服务器上共享它们。如果链接被破坏,稍后面对相同问题的人将无法找到它们。 – Ezze

回答

3

您的ChangeEmailForm以下rules()方法:

public function rules() 
{ 
    return array(
     array('newemail, password', 'required'), 
     array('newemail', 'email'), 
     array('newemail', 'unique', 'attributeName'=>'User.email'), 
     array('password', 'authenticate'), 
    ); 
} 

人们可以看到用于newemail属性unique验证只能应用于CActiveRecord通过tableName()但不CFormModel一些数据库表链接:

验证属性值在相应的数据库表中是唯一的。

相反,你可以write a custom validation method为表单模型来测试输入的电子邮件是否已经存在由User模型表示数据库表。

+0

没错!谢谢) – frops