这是与this one非常相似的问题,但表之间的关系不同。
我有3个表:users
,notifications
和user_notifications
。 user_notifications
是用户和通知之间的连接表,表示已发送给用户的通知实例。
关系如下:
User => hasMany => UserNotification
UserNotification => belong to => User, Notification
Notification => hasMany => UserNotification
列如下:
用户=> id,名称
UserNotification => id,user_id,notification_id
通知=> id,消息
我想创建一个名为Notification.users
的虚拟字段,它只包含已发送该特定通知的所有用户的字符串列表,例如:
User => id = 1, name = Bob
User => id = 2, name = Bill
UserNotification => id = 1, user_id = 1, notification_id = 1
UserNotification => id = 2, user_id = 2, notification_id = 1
Notification => id = 1, message = "Hello World!"
通知1,“Hello World!”已经发送给用户1和2,鲍勃和比尔。因此,虚拟字段Notification.users
包含这两个名称的逗号分隔列表,我看到了:
Notification => id = 1, message = "Hello World!", users = "Bob,Bill"
答案 0 :(得分:0)
最终为我工作的代码是:
class Notification extends AppModel
{
public $virtualFields = array(
"users" => "SELECT string_agg(users.name, ',') FROM users where users.id IN (SELECT user_notifications.user_id FROM user_notifications where user_notifications.notification_id = Notification.id)"
);
string_agg()
使用提供的可选分隔符将所选列聚合为字符串。我最初遇到的一个问题是其他表的CakePHP别名(“User”,“UserNotification”)的用户;这导致“table not provided”错误,所以我使用了实际的数据库表名。默认情况下,值不按特定顺序馈送到string_agg()
,这可能会导致字符串混乱。 string_agg()
支持order by子句来解决此问题,如下所示(请注意分隔符','
和order by子句之间缺少逗号):
class Notification extends AppModel
{
public $virtualFields = array(
"users" => "SELECT string_agg(users.name, ',' ORDER BY users.name) FROM users where users.id IN (SELECT user_notifications.user_id FROM user_notifications where user_notifications.notification_id = Notification.id)"
);
这对我来说似乎是最简单的解决方案。有更优雅或更正确的吗?