2008-11-29 9 views
7

Я работаю над приложением CakePHP 1.2. У меня есть модель «Пользователь», определенная с несколькими отношениями HABTM с другими таблицами через таблицу соединений.Как мне запрашивать данные в CakePHP, используя отношения HABTM?

Теперь мне поручено находить информацию о пользователе на основе данных, хранящихся в одной из этих таблиц HABTM. К сожалению, когда запрос выполняется, мое условие отклоняется с ошибкой об отсутствующей таблице. При проверке кажется, что CakePHP не включает ни одну из таблиц HABTM в инструкции select.

Мои отношения HABTM Пользователь следующим образом:

var $hasAndBelongsToMany = array(
    'Course' => array(
     'className'    => 'Course', 
     'joinTable'    => 'course_members', 
     'foreignKey'    => 'user_id', 
     'associationForeignKey' => 'course_id', 
     'conditions'    => '', 
     'order'     => '', 
     'limit'     => '', 
     'uniq'     => false, 
     'finderQuery'   => '', 
     'deleteQuery'   => '', 
     'insertQuery'   => '' 
    ), 
    'School' => array(
     'className'    => 'School', 
     'joinTable'    => 'school_members', 
     'foreignKey'    => 'user_id', 
     'associationForeignKey' => 'school_id', 
     'conditions'    => '', 
     'order'     => '', 
     'limit'     => '', 
     'uniq'     => false, 
     'finderQuery'   => '', 
     'deleteQuery'   => '', 
     'insertQuery'   => '' 
    ), 
    'Team' => array(
     'className'    => 'Team', 
     'joinTable'    => 'team_members', 
     'foreignKey'    => 'user_id', 
     'associationForeignKey' => 'team_id', 
     'conditions'    => '', 
     'order'     => '', 
     'limit'     => '', 
     'uniq'     => false, 
     'finderQuery'   => '', 
     'deleteQuery'   => '', 
     'insertQuery'   => '' 
    ) 
); 

Ошибка:

SQL Error: 1054: Unknown column 'School.name' in 'where clause'

И, наконец, запрос он пытается выполнить

 SELECT 
`User`.`id`, `User`.`username`, `User`.`password`, `User`.`firstName`, `User`.`lastName`, `User`.`email 

`, `User`.`phone`, `User`.`streetAddress`, `User`.`city`, `User`.`province`, `User`.`country`, `User 

`.`postal`, `User`.`userlevel`, `User`.`modified`, `User`.`created`, `User`.`deleted`, `User`.`deleted_date 

` FROM `users` AS `User` WHERE `User`.`id` = 6 AND `School`.`name` LIKE '%Test%' LIMIT 1 

ответ

0

FWIW, ваш таблицы соединений выглядят как «странно названные», поскольку они не следуют описанному здесь соглашению:

http://book.cakephp.org/view/83/hasAndBelongsToMany-HABTM

В любом случае, удачи, я помню HABTM будучи стыковой боль в CakePHP.

+0

Как лучше всего, как я знаю, что это не имеет значения, как Я явно задал имена совместной таблицы и модели. – 2008-11-29 15:11:09

7

Включите уровень отладки до 2 и посмотрите на выход SQL. Найдите запрос, который генерирует ваш код, и вы заметите, что его несколько. Уровень ORM в CakePHP не присоединяется к связанным с HABTM таблицам в первом запросе. Он получает результаты от первого выбора, затем отдельно извлекает данные HABTM для каждого элемента. Поскольку таблица соединений не входит в первый запрос, ваше условие, предназначенное для использования в объединенной таблице, приводит к ошибке, которую вы видите.

Книга повара содержит раздел HABTM associations и выбор данных на основе условий в таблице HABTM, которые соответствуют вашим требованиям.

+0

Спасибо, информация Legit. – usumoio 2013-06-05 18:39:09

2

Ваш стол должен называться «school_users», а не «school_members», потому что это много-ко-многим, поэтому использование множественной формы в имени таблицы с обеих сторон является подходящим.

Вы также устанавливаете модель ClassName «Школа» как псевдоним для HABTM. Вы должны изменить это на нечто более общее, например «Школы», как в «Пользователь включен и имеет много школ», чтобы избежать конфликтов.

И еще один намек: попробуйте найти пользователя «через» модель школы, а не модель пользователя.

$ this-> User-> Schools-> найти()

Надеется, что это помогает.

5

Из Cookbook: http://book.cakephp.org/view/83/hasAndBelongsToMany-HABTM

Одним из вариантов является поиск модели Tag (вместо рецепта), который также даст нам все связанные рецепты.

$this->Recipe->Tag->find('all', array(
    'conditions' => array('Tag.name' => 'Dessert'))); 

Мы также могли бы использовать модель таблицы объединения (который CakePHP предоставляет нам), для поиска данного идентификатора.

$this->Recipe->bindModel(array('hasOne' => array('RecipesTag'))); 
$this->Recipe->find('all', array(
    'fields' => array('Recipe.*'), 
    'conditions' => array('RecipesTag.tag_id' => 124) // id of Dessert 
)); 

Также можно создать экзотическую ассоциацию с целью создания как многие присоединяются по мере необходимости, чтобы фильтровать, например:

$this->Recipe->bindModel(array('hasOne' => array('RecipesTag', 
    'FilterTag' => array(
     'className' => 'Tag', 
     'foreignKey' => false, 
     'conditions' => array('FilterTag.id = RecipesTag.tag_id') 
)))); 
$this->Recipe->find('all', array(
    'fields' => array('Recipe.*'), 
    'conditions' => array('FilterTag.name' => 'Dessert') 
)); 
+1

Это был, я считаю, лучший ответ. Одна вещь, которую следует учитывать, состоит в том, что вы должны убедиться, что использование «найти» содержит на модели, которую вы привязали. Таким образом, после ваших условий «содержать» => «FilterTag». – TeckniX 2013-01-04 20:41:55