2013-06-20 39 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