CakePHP не тянет строки за определенное число для отношения hasOne - PullRequest
2 голосов
/ 28 апреля 2011

У меня есть клиент с базой данных, которая имеет несколько масштабных и взаимосвязанных моделей.Мы столкнулись со странной «ошибкой» в отношениях с $ hasOne, которые мы производим.Проблема заключается в следующем:

Модель UsersItems имеет отношение $ hasOne с пользователями.Это выглядит следующим образом:

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

Это извлекает и объединяет пользовательские данные с псевдонимом «Автор» для этих элементов (которые также принадлежат Пользователям в контексте пользователей, которые выбрали их для «закладки»).

Если у UserItem есть id, скажем, 3445 (больше середины диапазона текущего размера таблицы), он прекрасно справляется.

Однако, если UserItem имеет, скажем, id 5000 (верхний диапазон текущего размера таблицы), $ 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 в качестве идентификатора автора, поэтому я знаю, что это была проблема;сейчас я пытаюсь выяснить, как заставить Cake сгенерировать этот правильный запрос ...

Ответы [ 4 ]

4 голосов
/ 04 мая 2011

Может быть, вам следует переключить отношение Author на assignTo вместо hasOne в вашем элементе Модель, подобная этой:

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

книга очень хорошо объясните, вам нужен внешний ключ в отношении:

foreignKey: имя внешнего ключа, найденного в текущей модели. Это особенно удобно, если вам нужно определить несколько отношений ownTo. Значением по умолчанию для этого ключа является подчеркнутое единственное имя другой модели с суффиксом «_id».

Надеюсь, я помог :).

3 голосов
/ 04 мая 2011

Если я правильно понял ваш запрос, ваша ассоциация должна была выглядеть следующим образом:

В модели UserItem:

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

В модели элемента:

var $hasMany = array(
    'UserItem'
);

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

Надеюсь, это поможет.

2 голосов
/ 05 мая 2011

Ни один из ответов здесь не сработал для меня. Что бы там ни было, я закончил тем, что создал виртуальное поле, которое заполнило бы значение имени автора.

Проблема с моделью отношений заключается в том, что они применяются только тогда, когда вы вызываете данную модель. В моем случае нет (и не должно быть) никакой связи между таблицей UsersItems и именем человека, который создал рассматриваемый элемент.

Виртуальные таблицы вызываются в каждый экземпляр внешнего вида этой модели. Это означает, что даже в отношении UsersItems-> Items Items будет заполнять его виртуальные поля.

То, что я создал в файле модели item.php, выглядело примерно так:

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

Я буду ждать ответа от других о том, подходит ли это решение этой проблемы или нет, но пока оно единственное, которое сработало для меня. Поскольку в таблице UsersItems нет ассоциированного столбца author_id, я просто не понимаю, как можно связать эти две таблицы.

1 голос
/ 28 апреля 2011

Мое дикое предположение состоит в том, что в какой-то момент идентификаторы Author и UserItem вышли из синхронизации, т.е. идентификатор автора 3445 hasOne идентификатор UserItem 3445, но идентификатор автора 5000 hasOne UserItem 5001 или что-то еще, и запрос пытается извлечь идентификатор неправильный стол Но не видя сгенерированные запросы, трудно сказать.

...