query fields consultas complejas cake php cakephp cakephp-1.3 has-and-belongs-to-many

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:

¡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.