CakePHP - HABTM分页查询的问题

Dav*_*ave 5 php cakephp has-and-belongs-to-many cakephp-1.3

restaurants
cuisines
cuisines_restaurants
Run Code Online (Sandbox Code Playgroud)

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

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

1054: Unknown column 'Cuisine.name' in 'where clause'
Run Code Online (Sandbox Code Playgroud)

它正在构建的实际查询:

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
Run Code Online (Sandbox Code Playgroud)

"....."部分只是我删除的其他字段,以缩短查询以向您显示.

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

$this->paginate = array(
    'conditions' => $opts,
    'limit' => 10,
);
$data = $this->paginate('Restaurant');
$this->set('data', $data);
Run Code Online (Sandbox Code Playgroud)

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

我也试过设置$ 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'
    )
);
Run Code Online (Sandbox Code Playgroud)

vin*_*dia 6

正如这篇博文中所解释的那样,你必须将相关模型的条件放在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'));
Run Code Online (Sandbox Code Playgroud)


dec*_*lan 5

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

正如@vindia 在这里解释的那样,使用Containable行为通常可以解决这个问题,但它不适用于Paginate.

基本上,您需要一种方法来强制Cake在第一次查询期间查看Cuisine.这不是框架通常做事的方式,所以不幸的是,它需要手动构建连接 . paginate采用相同的选项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
);
Run Code Online (Sandbox Code Playgroud)

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