CakePHP不拉行超过一定数量的hasOne关系


CakePHP not pulling rows over a certain number for hasOne relationship

我有一个客户端,它的数据库有几个相当大的相互关系的模型。我们在制作$hasOne关系时遇到了一个奇怪的"bug"。问题是:

模型UsersItems与Users有一个$hasOne关系。内容如下

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

将这些条目的用户数据与别名"Author"连接起来(这些条目在选择它们作为"书签"的用户的上下文中也属于Users)。

如果UserItem的id为3445(表当前大小范围的中间位置),则它可以顺利通过。

然而,如果UserItem的id为5000(表当前大小的上限),则$hasOne无法从find()中提取任何信息。因此,看起来较新的"书签"条目不能检索Author数据,而其他的("较旧的")则可以。

是什么引起的?

<

添加信息/strong>

查询方式如下:

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,所以我知道这就是问题所在;现在我想弄清楚如何让蛋糕生成这个正确的查询…

也许你应该在你的项目模型中将Author关系切换为belongsTo而不是hasOne,像这样:

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

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

foreignKey:在当前模型中找到的外键的名称。如果需要定义多个belongsTo关系,这尤其方便。此键的默认值是另一个模型的下划线单数名称,以' _id '结尾。

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

On UserItem model:

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

On Item model:

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

这里的答案都不适合我。不管是好是坏,我最后做的是创建一个虚拟字段来填充Author的name值。

关系模型的问题是它们只适用于当你通过有问题的模型调用时。在我的例子中,UsersItems表和所讨论的项目的作者的名字之间没有(也不应该有)任何关系。

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

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

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

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

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