fields - CakePHP-problema con la consulta de paginación HABTM
findby cake php (5)
Mesas
restaurants
cuisines
cuisines_restaurants
Tanto el restaurante como el modelo de cocina están configurados para HABTM entre sí.
Estoy tratando de obtener una lista paginada de restaurantes donde Cuisine.name = ''italian'' (ejemplo), pero sigo recibiendo este error:
1054: Unknown column ''Cuisine.name'' in ''where clause''
Consulta real está construyendo:
SELECT `Restaurant`.`id`, `Restaurant`.`type` .....
`Restaurant`.`modified`, `Restaurant`.`user_id`, `User`.`display_name`,
`User`.`username`, `User`.`id`, `City`.`id`,`City`.`lat` .....
FROM `restaurants` AS `Restaurant` LEFT JOIN `users` AS `User` ON
(`Restaurant`.`user_id` = `User`.`id`) LEFT JOIN `cities` AS `City` ON
(`Restaurant`.`city_id` = `City`.`id`) WHERE `Cuisine`.`name` = ''italian''
LIMIT 10
Las partes "....." son solo campos adicionales que eliminé para acortar la consulta que se te muestra.
No soy un profesional de CakePHP, así que espero que haya un error evidente. Estoy llamando a la paginación de esta manera:
$this->paginate = array(
''conditions'' => $opts,
''limit'' => 10,
);
$data = $this->paginate(''Restaurant'');
$this->set(''data'', $data);
$ opts es una matriz de opciones, una de las cuales es ''Cuisine.name'' => ''italian''
También intenté configurar $ this-> Restaurant-> recursive = 2; pero eso no pareció hacer nada (¿y asumo que no debería tener que hacer eso?)
Cualquier ayuda o dirección es muy apreciada.
EDITAR
models/cuisine.php
var $hasAndBelongsToMany = array(''Restaurant'');
models/restaurant.php
var $hasAndBelongsToMany = array(
''Cuisine'' => array(
''order'' => ''Cuisine.name ASC''
),
''Feature'' => array(
''order'' => ''Feature.name ASC''
),
''Event'' => array(
''order'' => ''Event.start_date ASC''
)
);
algunas ideas en lo más alto de mi mente:
- ¿Has revisado el modelo para ver si el HABTM está bien declarado?
- intente usar el comportamiento contenible
- en ninguno de esos trabajos ... entonces siempre podrías construir las uniones para el paginador manualmente
¡buena suerte!
Como lo explicaste en este blog mío, debes poner la condición del modelo relacionado en la opción contain
de tu matriz de paginación.
Entonces algo como esto debería funcionar
# in your restaurant_controller.php
var $paginate = array(
''contain'' => array(
''Cuisine'' => array(
''conditions'' => array(''Cuisine.name'' => ''italian'')
)
),
''limit'' => 10
);
# then, in your method (ie. index.php)
$this->set(''restaurants'', $this->paginate(''Restaurant''));
Cuisine
debe ser una tabla (o alias) en la clausula FROM de su SELECT. entonces el error:
1054: columna desconocida ''Cuisine.name'' en ''where clause''
Es solo porque no está referenciado en el FROM clausule
Si elimina la parte de Función y Evento de su enlace HABTM en el modelo de Restaurante, ¿funciona entonces? Me parece que no ha podido definir las claves primarias y externas correctas para el modelo de cocina, ya que el modelo HABTM ni siquiera incluye la tabla de cocina en la consulta que publicó aquí.
Esto falla porque Cake está usando 2 consultas diferentes para generar su conjunto de resultados. Como habrás notado, la primera consulta ni siquiera contiene una referencia a la cocina.
Como se explica en @vindia aquí , usar el comportamiento Containable generalmente solucionará este problema, pero no funciona con Paginate .
Básicamente, necesitas una forma de obligar a Cake a mirar Cuisine durante la primera consulta. Esta no es la forma en que el framework generalmente hace las cosas, por lo que, desafortunadamente, requiere construir el join manualmente . paginate
toma las mismas opciones que Model->find(''all'')
. Aquí, necesitamos usar la opción de joins
.
var $joins = array(
array(
''table'' => ''(SELECT cuisines.id, cuisines.name, cuisines_restaurants.restaurant_id
FROM cuisines_restaurants
JOIN cuisines ON cuisines_restaurants.cuisines_id = cuisines.id)'',
''alias'' => ''Cuisine'',
''conditions'' => array(
''Cuisine.restaurant_id = Restaurant.id'',
''Cuisine.name = "italian"''
)
)
);
$this->paginate = array(
''conditions'' => $opts,
''limit'' => 10,
''joins'' => $joins
);
Esta solución es mucho más ruidosa que las otras, pero tiene la ventaja de funcionar.