【问题标题】:CakePHP not pulling rows over a certain number for hasOne relationshipCakePHP 没有为 hasOne 关系拉出一定数量的行
【发布时间】:2011-04-28 05:16:46
【问题描述】:

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

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

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

这会为这些项目提取并加入别名为“作者”的用户数据(在用户选择它们进行“书签”的情况下,这些项目也属于用户)。

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

但是,如果一个 UserItem 具有 5000(表当前大小的上限)的 id,则 $hasOne 无法从 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 生成这个正确的查询......

【问题讨论】:

  • 生成的SQL查询是什么,怎么会失败?
  • 我会尽快更新这些内容。
  • 为原始问题添加了新信息。
  • 如果您在数据库上手动执行此查询是否有效? users 中是否有匹配 UsersItem.id 的条目?
  • 如果在数据库上手动执行,查询效果不会更好。相同的项目返回与作者有关​​的缺失信息。目前在用户中不存在与 UsersItem.id 匹配的相应条目。我想我看到了答案的走向......

标签: php mysql cakephp relational-database cakephp-model


【解决方案1】:

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

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

book 解释的很好,belongsTo 关系中的外键就是你需要的:

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

希望我能帮上忙 :) .

【讨论】:

    【解决方案2】:

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

    在 UserItem 模型上:

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

    关于项目模型:

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

    我希望这会有所帮助。

    【讨论】:

    • 如何查询模型?使用可包含的行为?我们可以获取您正在执行的查找查询吗?
    • 这未经测试。我只是边想边打的。
    【解决方案3】:

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

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

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

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

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

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

    【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      相关资源
      最近更新 更多