CakePHP如何检索具有条件的HABTM数据?

CakePHP如何检索具有条件的HABTM数据?,php,cakephp,has-and-belongs-to-many,Php,Cakephp,Has And Belongs To Many,我使用CakePHP2.2.2 我有3张桌子:餐厅、厨房和厨房餐厅-HABTM的join table 在餐厅模式中,我有: public $hasAndBelongsToMany = array( 'Kitchen' => array( 'className' => 'Kitchen', 'joinTable' => 'kitchens_restauran

我使用CakePHP2.2.2 我有3张桌子:餐厅、厨房和厨房餐厅-HABTM的join table

在餐厅模式中,我有:

public $hasAndBelongsToMany = array(
    'Kitchen' =>
        array(
            'className'              => 'Kitchen',
            'joinTable'              => 'kitchens_restaurants',
            'foreignKey'             => 'restaurant_id',
            'associationForeignKey'  => 'kitchen_id',
            'unique'                 => true,
            'conditions'             => '',
            'fields'                 => 'kitchen',
            'order'                  => '',
            'limit'                  => '',
            'offset'                 => '',
        ),
问题是我的主页有单独的控制器,在其中我需要从复杂条件下的模型中检索数据

我补充说

public $uses = array('Restaurant');
到我的主页控制器,这里来的部分,我需要你的建议

我只需要选择厨房=$id的餐厅。 我试着补充一下

public function index() {   
$this->set('rests', $this->Restaurant->find('all', array(
'conditions' => array('Restaurant.active' => "1", 'Kitchen.id' => "1")
)));

}
我得到了SQLSTATE[42S22]:Column not found:1054“where子句”错误中的未知列。 显然,我需要从“HABTM连接表”中获取数据,但我不知道如何获取。

TLDR:

要检索基于条件限制的数据(针对的关联),您需要使用

说明:

下面的代码遵循了这个咒语,所以逻辑大部分都在模型中,并且只是从控制器调用

注意:如果您遵循(看起来是这样的),则不需要所有这些HABTM参数

下面的代码还没有经过测试(我是在这个网站上写的),但它应该非常接近,至少可以让你走上正确的方向

代码:

//餐厅模式

public $hasAndBelongsToMany = array('Kitchen');

/**
 * Returns an array of restaurants based on a kitchen id
 * @param string $kitchenId - the id of a kitchen
 * @return array of restaurants
 */
public function getRestaurantsByKitchenId($kitchenId = null) {
    if(empty($kitchenId)) return false;
    $restaurants = $this->find('all', array(
        'joins' => array(
             array('table' => 'kitchens_restaurants',
                'alias' => 'KitchensRestaurant',
                'type' => 'INNER',
                'conditions' => array(
                    'KitchensRestaurant.kitchen_id' => $kitchenId,
                    'KitchensRestaurant.restaurant_id = Restaurant.id'
                )
            )
        ),
        'group' => 'Restaurant.id'
    ));
    return $restaurants;
}
//任何控制器

public function whateverAction($kitchenId) {
    $this->loadModel('Restaurant'); //don't need this line if in RestaurantsController
    $restaurants = $this->Restaurant->getRestaurantsByKitchenId($kitchenId);
    $this->set('restaurants', $restaurants);
}

您不需要使用[join],因为use具有设置[HABTM]的关联
厨房模型有ANDBELONGTOMANY餐厅模型,因此您可以按以下方式编码

KitchensControllers
<?php
  public function index() {
    $this->Kitchen->recursive = 0;
    $kitchens = $this->Kitchen->find('all', array('contain' => array('Restaurant')));
    $this->set('kitchens', $kitchens);
  }
?>
厨房控制器

祝你好运

有一种比Dave提供的解决方案更干净的方法

首先,您需要在厨房模型中设置餐厅和厨房之间的反向HABTM关系。

然后,您只需查找您感兴趣的厨房(id=1),就可以得到相关的餐厅,用于按餐厅字段过滤


戴夫,谢谢你。你的代码运行得很好。一个小问题-是否可以只选择我想要的字段(例如,我只需要公司名称和一些其他信息,而不是所有字段)?我已经尝试将'fields'=>array('Restaurant.companyname')添加到函数getRestaurantsByKitchenId(在餐馆模型中)中,但没有产生任何效果。@user1327-很乐意提供帮助。是的,您应该能够将'fields'=>array()添加到Model方法中。只要把它放在与“连接”相同的级别(不在内部)。您可以随时使用DebugKit轻松查看正在运行的查询,并可以在此基础上进行调整。哦,我真傻。现在一切都按照我的要求进行。再次感谢。谢谢你的回答,你为我节省了很多时间。再次感谢。有可能将这种方法与分页结合使用吗?这不会返回所有厨房吗?是的,我认为这会返回所有厨房。但是,该代码对于查找模型A中的所有记录并显示模型B中的相关HABTM记录是正确的。是的,如果您想查找可以用作以下示例的条件,则返回所有Kitchen:$this->Kitchen->find('all',array('conditions'=>array('Kitchen.id>'=>'5'),'contain=>array('Restaurant'))这代表什么?“$this->餐厅->厨房->”
$this->Restaurant->Kitchen->Behaviors->attach('containable'); // Enable Containable for Kitchen Model

$this->Restaurant->Kitchen->find('first', array(
    'recursive' => -1 // don't collect other data associated to Kitchen for performance purpose
    'conditions' => array('Kitchen.id' => 1),
    'contain' => array('Restaurant.active = 1')
));