2

我有一个客户,它的数据库有几个相当大的相互关系模型。我们在生成的 $hasOne 关系中遇到了一个奇怪的“错误”。问题是这样的:

模型 UsersItems 与 Users 具有 $hasOne 关系。如下

var $hasOne = array(
    'Author' => array(
        'className' => 'User',
        'foreignKey' => 'id'
    )
);

这将使用这些项目的别名“作者”提取并连接用户数据(在用户选择它们进行“书签”的上下文中,这些数据也属于用户)。

如果 UserItem 有一个id,比如说,3445(表的当前大小范围的中间值),它就可以通过。

但是,如果 UserItem 具有id5000 的 an(表当前大小的上限),则 $hasOne 无法从 a 中提取任何信息find()。因此,似乎较新的“书签”项目不会检索作者数据,而其他(“旧”)项目则很好。

什么会导致这种情况?

附加信息

查询如下:

SELECT `UsersItem`.`id`, `UsersItem`.`user_id`, `UsersItem`.`item_id`,
       `UsersItem`.`in_list`, `User`.`id`, `User`.`username`, `User`.`password`,
       `User`.`email`, `User`.`group_id`, `User`.`resethash`, `User`.`confirmhash`,
       `User`.`confirmed`, `Item`.`id`, `Item`.`user_id`, `Item`.`name`,
       `Item`.`category_id`, `Item`.`description`, `Item`.`pagelink`,
       `Item`.`purchaselink`, `Item`.`moderated`, `Item`.`image_filename`,
       `Item`.`votecount`, `Item`.`parent_id`, `Item`.`discover_order`,
       `Item`.`created`, `Item`.`slug`, `Item`.`normalized_name`,
       ((`Item`.`votecount`)/pow((3600*TIMEDIFF(`Item`.`created`, NOW()) + 12), .42)) AS `Item__rank`,
       `Author`.`id`, `Author`.`username`, `Author`.`password`, `Author`.`email`,
       `Author`.`group_id`, `Author`.`resethash`, `Author`.`confirmhash`,
       `Author`.`confirmed`
FROM `users_items` AS `UsersItem`
LEFT JOIN `users` AS `User` ON (`UsersItem`.`user_id` = `User`.`id`)
LEFT JOIN `items` AS `Item` ON (`UsersItem`.`item_id` = `Item`.`id`)
LEFT JOIN `users` AS `Author` ON (`Author`.`id` = `UsersItem`.`id`)
WHERE `UsersItem`.`user_id` = 1118
  AND `UsersItem`.`in_list` = 1
ORDER BY `UsersItem`.`id` DESC

第二个附录

此查询确实有效:

SELECT `UsersItem`.`id`, `UsersItem`.`user_id`, `UsersItem`.`item_id`, `UsersItem`.`in_list`, `User`.`id`, `User`.`username`, `User`.`password`, `User`.`email`, `User`.`group_id`, `User`.`resethash`, `User`.`confirmhash`, `User`.`confirmed`, `Item`.`id`, `Item`.`user_id`, `Item`.`name`, `Item`.`category_id`, `Item`.`description`, `Item`.`pagelink`, `Item`.`purchaselink`, `Item`.`moderated`, `Item`.`image_filename`, `Item`.`yeekcount`, `Item`.`parent_id`, `Item`.`discover_order`, `Item`.`created`, `Item`.`slug`, `Item`.`normalized_name`, ((`Item`.`yeekcount`)/pow((3600*TIMEDIFF(`Item`.`created`, NOW()) + 12), .42)) AS `Item__rank`, `Author`.`id`, `Author`.`username`, `Author`.`password`, `Author`.`email`, `Author`.`group_id`, `Author`.`resethash`, `Author`.`confirmhash`, `Author`.`confirmed` FROM `users_items` AS `UsersItem` LEFT JOIN `users` AS `User` ON (`UsersItem`.`user_id` = `User`.`id`) LEFT JOIN `items` AS `Item` ON (`UsersItem`.`item_id` = `Item`.`id`) LEFT JOIN `users` AS `Author` ON (`Author`.`id` = `Item`.`user_id`) WHERE `UsersItem`.`user_id` = 1118 AND `UsersItem`.`in_list` = 1 ORDER BY `UsersItem`.`id` DESC

请注意此特定位的区别:

LEFT JOIN `users` AS `Author` ON (`Author`.`id` = `Item`.`user_id`)

我之前把作者 id 拉错id了,所以我知道这是问题所在;现在我试图弄清楚如何让 Cake 生成这个正确的查询......

4

4 回答 4

4

也许你应该在你的项目模型中将 Author 关系切换到 belongsTo 而不是 hasOne ,如下所示:

var $BelongsTo= array(
'Author' = array(
    'className' => 'User',
    'foreignKey' => 'user_id');

本书解释得很好,belongsTo关系中的外键是你需要的:

foreignKey:在当前模型中找到的外键的名称。如果您需要定义多个 belongsTo 关系,这将特别方便。此键的默认值是另一个模型的带下划线的单数名称,后缀为“_id”。

希望我有所帮助:)。

于 2011-05-04T10:40:13.153 回答
3

如果我正确理解了您的查询,您的关联应该是这样的:

在 UserItem 模型上:

var $belongsTo= array(
    'User', 'Item'
);

在项目模型上:

var $hasMany = array(
    'UserItem'
);

var $hasOne = array(
    'Author' = array(
        'className' => 'User',
        'foreignKey' => 'id'
);

我希望这有帮助。

于 2011-05-04T09:24:16.737 回答
2

这里没有一个答案对我有用。不管好坏,我最终做的是创建一个虚拟字段来填充作者姓名的值。

关系模型的问题在于它们仅在您通过相关模型调用时才适用。在我的情况下,UsersItems 表与相关项目的作者姓名之间没有(也不应该)任何关系。

在该模型外观的每个实例中都会调用虚拟表。这意味着,即使在 UsersItems->Items 关系中,Items也会填充其虚拟字段。

我最终在 item.php 模型文件中创建的内容看起来有点像:

var $virtualFields = array(
    'author' => 'SELECT `username` FROM `users` WHERE `id = Item.user_id`'
);

我会等待其他人的回复,看看这是否是解决这个问题的合适方法,但这是迄今为止唯一对我有用的方法。因为在 UsersItems 表中没有关联author_id的列,所以我只是看不出如何将这两个表关联起来。

于 2011-05-04T20:17:40.607 回答
1

我的疯狂猜测是,在某些时候 Author 和 UserItem 的 id 已经不同步,即 Author id 3445 hasOne UserItem id 3445 但 Author id 5000 hasOne UserItem 5001 或其他东西,并且查询尝试获取错误表的 id。但是如果没有看到生成的查询,就很难说。

于 2011-04-28T10:42:34.997 回答