Yii框架-获得关于属于其他模型的字段的验证反馈


Yii Framework - Getting validation feedback on fields beloning to other models

我是Yii framework的新手,到目前为止我很喜欢使用它。我正在独自完成我的第一个项目,我有点陷入了以下问题。

我有两个型号StudentTeacher。它们与外键无关,但学生表有一个属于Teacher表的teacher_id字段。(还不太清楚如何将它们联系起来,但这是我稍后不得不担心的另一个故事)。

当使用该表单更新视图中的"学生"时,我也为老师合并了该表单(全名、年龄等),但作为"学生"表单的一部分,它不会受益于"学生"模型中设置的验证规则。当我保存教师信息时(在同一POST请求期间,在保存学生字段之前),验证似乎有效,因为如果缺少必填字段,它不会保存它,但它不会返回到学生表单,验证错误就像它自己的必填字段一样。我希望这不会太令人困惑,但我不知道如何更好地解释它

任何想法都非常受欢迎!

您可以在模型文件中用这种格式声明关系,不需要有外键来声明关系,但如果有外键,您的查询会执行得更快。。。

'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)

你的例子可能是。。

public function relations() {   
    return array(
        'student' => array(self::BELONGS_TO, 'teacher', 'teacher_id'),
    );
}

关于在同一形式中使用多个模型的查询,从您的描述中还不太清楚到底发生了什么,根据我的理解,您正在使用同一形式的多个表模型,尽管这可能非常复杂。

我建议您使用单个表单创建一个单独的表单模型来处理多个表条目

我不确定我是否正确理解你的问题,但如果你想以相同的形式验证和保存两个模型,你可以这样做。

控制器:

$teacherModel = new Teacher;
$studentModel = new Student;
if(isset($_POST['Teacher']) && isset($_POST['Student']))
{
    $teacherModel->attributes = $_POST['Teacher'];
    $studentModel->attributes = $_POST['Student'];
    // check both models for validation errors before saving and redirecting.
    $teacherValid = $teacherModel->validate();
    $studentValid = $studentModel->validate();
    if($teacherValid && $studentValid)
    {
        $teacherModel->save(false);  // false = don't perform validation before saving
        $studentModel->save(false);
        $this->redirect(array('view','id'=>$studentModel->id));
    }
}
$this->render('create',array(
        'teacherModel'=>$teacherModel,
        'studentModel'=>$studentModel,
    ));

这将确保在重定向之前两个模型都是有效的,否则它将返回到表单

然后,您可以在视图中显示两个模型的验证错误,方法是将它们以数组形式传递给$form->errorSummary:

<?php echo $form->errorSummary(array($teacherModel, $studentModel)); ?>

所以我尝试了这个(Christian建议的),虽然验证似乎有效,但errorSummary方法并不能完成它的工作。如果我错过了教师表单上的必填字段,它不会保存它,但不会返回错误摘要。我注意到有趣的是,如果在学生表格中我遗漏了一个必填字段,它会给我漂亮的红色错误字段,但在我在这些字段中输入了一些内容,并且在教师表格中遗漏了一个子字段后,这一次确实会显示教师的错误摘要。这有点令人困惑。最后我走了另一条路。我首先检查Teacher表单,如果它没有验证,我会遍历Teacher->model()->error,创建一个无序列表,并将其作为flash消息发送给查看器。到目前为止,这种方式还可以。也许在将来,随着我的知识越来越多,我可以返回并改进这个代码。