在 CakePHP 框架中,我长期以来一直遇到问题的一件事是定义两个模型之间的同步hasOne
和hasMany
关系。例如:
BlogEntry hasMany Comment
BlogEntry hasOne MostRecentComment
(最近的字段MostRecentComment
在哪里)Comment
created
在 BlogEntry 模型属性中定义这些关系是有问题的。CakePHP 的 ORM 将 has-one 关系实现为INNER JOIN
,因此只要有多个 Comment,BlogEntry::find('all')
调用就会返回每个 BlogEntry 的多个结果。
过去我曾通过几种方式解决过这些情况:
使用模型回调(或者,有时,甚至在控制器或视图中!),我已经模拟了一个 MostRecentComment :
$this->data['MostRecentComment'] = $this->data['Comment'][0];
如果我需要以除 by 以外的任何方式订购 Comments,这会很快变得丑陋Comment.created
。它也没有 Cake 的内置分页功能来按 MostRecentComment 字段排序(例如,将 BlogEntry 结果按MostRecentComment.created
.维护一个额外的外键,
BlogEntry.most_recent_comment_id
. 这很烦人,并且破坏了 Cake 的 ORM:含义是BlogEntry belongsTo MostRecentComment
. 它有效,但只是看起来......错了。
这些解决方案还有很多不足之处,所以前几天我坐下来解决这个问题,并研究了一个更好的解决方案。我已经在下面发布了我的最终解决方案,但是我很高兴(也许只是有点羞愧)发现有一些令人难以置信的简单解决方案一直以来都在逃避我。或任何其他符合我标准的解决方案:
- 它必须能够按该
Model::find
级别的 MostRecentComment 字段进行排序(即,不仅仅是结果的按摩); - 它不应该需要
comments
orblog_entries
表中的其他字段; - 它应该尊重 CakePHP ORM 的“精神”。
(我也不确定这个问题的标题是否尽可能简洁/信息丰富。)