CakePHP - HABTM分页查询的问题

时间:2011-04-13 21:35:34

标签: php cakephp cakephp-1.3 has-and-belongs-to-many

restaurants
cuisines
cuisines_restaurants

餐厅和美食模型都是HABTM彼此设置的。

我正在尝试获取一个餐馆的分页列表,其中Cuisine.name ='italian'(示例),但不断收到此错误:

1054: Unknown column 'Cuisine.name' in 'where clause'

实际查询它正在构建:

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

“.....”部分只是我删除的其他字段,以缩短查询以显示。

我不是CakePHP专家,所以希望有一些明显的错误。我正在调用这样的分页:

$this->paginate = array(
    'conditions' => $opts,
    'limit' => 10,
);
$data = $this->paginate('Restaurant');
$this->set('data', $data);

$ opts是一系列选项,其中一个是'Cuisine.name'=> '意大利'

我也试过设置$ this-> Restaurant-> recursive = 2;但这似乎没有做任何事情(我认为我不应该这样做?)

非常感谢任何帮助或指示。


修改

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

5 个答案:

答案 0 :(得分:6)

this blogpost by me中所述,您必须将相关模型的条件放在分页数组的contain选项中。

所以这样的事情应该有用

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

答案 1 :(得分:5)

这失败了,因为Cake实际上使用了2个不同的查询来生成结果集。正如您所注意到的,第一个查询甚至没有包含对Cuisine的引用。

正如@vindia解释here一样,使用Containable行为通常会解决此问题,但不适用于Paginate

基本上,您需要一种方法来强制Cake在第一次查询期间查看Cuisine。这不是框架通常做事的方式,所以不幸的是,它需要constructing the join manuallypaginate采用与Model->find('all')相同的选项。在这里,我们需要使用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
);

这个解决方案比其他解决方案更笨拙,但具有工作的优势。

答案 2 :(得分:0)

我想到的一些想法:

祝你好运!

答案 3 :(得分:0)

Cuisine必须是SELECT的FROM clausule上的表(或别名)。 所以错误:
1054:'where子句'中的未知列'Cuisine.name' 只是因为它没有在FROM clausule上引用

答案 4 :(得分:0)

如果您删除了餐厅模型中HABTM链接的功能和事件部分,那么它是否有效? 听起来像你没有为烹饪模型定义正确的主要和前置键,因为HABTM模型甚至不包括您在此处发布的查询中的烹饪表。