2008-11-29 13 views
7

Estoy trabajando en una aplicación CakePHP 1.2. Tengo un modelo "Usuario" definido con algunas relaciones HABTM con otras tablas a través de una tabla de unión.¿Cómo consulto datos en CakePHP usando relaciones HABTM?

Ahora tengo la tarea de encontrar información de usuario basada en los datos almacenados en una de estas tablas HABTM. Lamentablemente, cuando se ejecuta la consulta, mi condición se rechaza con un error sobre la falta de una tabla. Tras la inspección, parece que CakePHP no incluye ninguna de las tablas HABTM en la declaración seleccionada.

Mi relación HABTM usuario es el siguiente:

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'   => '' 
    ) 
); 

El error es:

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

Y, por último, la consulta se está tratando de ejecutar

 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 

Respuesta

0

Fwiw, su Las tablas de combinación parecen ser "extrañamente nombradas" en la medida en que no siguen la convención que se describe aquí:

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

En cualquier caso, buena suerte, recuerdo HABTM ser un tope dolor en CakePHP.

+0

Como mejor que yo sepa esto no debería importar como Establecí explícitamente la tabla conjunta y los nombres de modelo. –

7

Convierta su nivel de depuración hasta 2 y mire la salida de SQL. Encuentra la consulta que está generando tu código y notarás que hay varios. La capa ORM en CakePHP no se une a las tablas relacionadas con HABTM en la primera consulta. Obtiene los resultados de la primera selección, luego obtiene por separado los datos HABTM para cada elemento. Debido a que la tabla de unión no está en la primera consulta, su condición, que debe usarse en una tabla unida, da como resultado el error que está viendo.

El libro de cocina tiene una sección en HABTM associations y busca datos según las condiciones de la tabla HABTM que se ajusten a sus necesidades.

+0

Gracias, información Legit. – usumoio

2

Su tabla debe llamarse "schools_users" y no "school_members" porque es many-to-many, por lo tanto, usar el formulario plural en el nombre de la tabla en ambos lados es apropiado.

También establece el Model ClassName "School" como Alias ​​para HABTM. Debe cambiar eso a algo más genérico como "Escuelas" como en "El usuario está en y tiene muchos SchoolS" para evitar conflictos.

Y otra sugerencia: Trate de encontrar al usuario "a través" del Modelo de la Escuela en lugar del Modelo de Usuario.

$ this-> User-> Schools-> find()

Espero que esto ayude.

5

Desde el libro de cocina: http://book.cakephp.org/view/83/hasAndBelongsToMany-HABTM

Una opción es buscar el modelo de etiqueta (en lugar de la receta), que también nos dará todas las recetas asociadas.

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

También podríamos utilizar el modelo de tabla de unión (que proporciona CakePHP para nosotros), para buscar una determinada identificación.

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

También es posible crear una asociación exótica con el propósito de crear tantas uniones como sea necesario para permitir el filtrado, por ejemplo:

$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

Esta fue, creo, la mejor respuesta. Una cosa a tener en cuenta es que debes asegurarte de que los usos 'buscar' contengan en el modelo que has enlazado. Así que 'contiene' => 'FilterTag' después de sus condiciones. – TeckniX

Cuestiones relacionadas