我已经回答了我自己的问题,但我不介意接受任何其他比我的方法更好的答案(提一下它是如何更好的)。请贡献。
我遇到的情况是User Model
,我有first_name, middle_name, last_name
个3个单独的字段,只有first_name
被empty/NULL
验证,即其他2个可以空/ NULL /空格(不想用不合理的验证来惹恼用户,我个人知道那些因某些疯狂的原因而没有使用姓氏的人。)
有了这样的结构,可以合理地期望displayfield
作为所有这3列的复合,记住其他2可能是"" / NULL / white-space (因为它们都是VARCHAR列)。此外,我的数据库表格包含created_by
,modified_by
,approved_by
,assigned_to
等列...(此模型的其他别名很多,但所有这些都很相关遵循" CakePHP惯例")。
我在SO official documentation上阅读了like this one和几个帖子。但是他们都没有为这种情况提供解决方案或样本。也许,我的数据库结构太不寻常了,或者我说'非正统'" ;)(好吧,官方文档确实回答了多个模型别名,我错过了几次,这促使我发布这个问题并在此处回答它。)
那么,问题是如何正确地解决这种模型关系和结构?
答案 0 :(得分:0)
<强> TL; DR; - 最后跳转到最终解决方案
我将分两部分回答我自己的问题 -
CakePHP 2.X的官方文档有一个关于Virtual fields and model aliases的部分。
当您使用虚拟字段和具有非别名的模型时 与其名称相同,您可以像virtualFields那样遇到问题 不更新以反映绑定别名。如果您使用的是virtualFields 在具有多个别名的模型中,最好定义 模型构造函数中的virtualFields
所以User.PHP
中的类似内容应允许virtualFields适用于您为模型提供的任何别名:
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->virtualFields['name'] = sprintf(
'CONCAT(%s.first_name, " ", %s.middle_name, " ", %s.last_name)', $this->alias, $this->alias, $this->alias
);
}
这可以通过模型构造函数中的一些额外SQL语法来解答,为简单起见,我使用CASE ... WHEN ... THEN ... ELSE ... END
,可以用更好的SQL代替(如果可能)。但是这个也不会失败(并且也不错)。
CONCAT(%s.first_name, CASE WHEN %s.middle_name = "" THEN " " ELSE CONCAT(" ", %s.middle_name, " ") END, %s.last_name)
在模型构造函数中:
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->virtualFields['full_name'] = sprintf(
'CONCAT(%s.first_name, CASE WHEN %s.middle_name = "" THEN " " ELSE CONCAT(" ", %s.middle_name, " ") END, %s.last_name)', $this->alias, $this->alias, $this->alias, $this->alias
);
}
最后,通常是public $displayField = 'full_name';
现在,无论您在控制器中执行$this->RelatedModel->UserAlias->find('list');
,您都会得到一个包含用户id
和full_name
的数组。
希望这可以帮助某人,或者至少为我自己担任期刊:)