CakePHP:belongsTo具有空值

CakePHP:belongsTo具有空值,cakephp,model,foreign-keys,relational-database,belongs-to,Cakephp,Model,Foreign Keys,Relational Database,Belongs To,我有一个模型,它有一个不需要的belongsTo关系 Banana belongsTo Basket banana.basket_id can be null 这意味着香蕉可以属于篮子,但不一定非得属于篮子 保存操作Banana->save(数组('Banana'=>array('basket_id'=>null,'weight'=>50))工作正常,但当我阅读时,我得到以下结果: array( 'Banana' => array('id' => 10, 'basket_id

我有一个模型,它有一个不需要的belongsTo关系

Banana belongsTo Basket
banana.basket_id can be null
这意味着香蕉可以属于篮子,但不一定非得属于篮子

保存操作
Banana->save(数组('Banana'=>array('basket_id'=>null,'weight'=>50))工作正常,但当我阅读时,我得到以下结果:

array(
   'Banana' => array('id' => 10, 'basket_id' => null, 'weight' => 50),
   'Basket' => array('id' => null, 'bannana_count' => null)
)
当然,我可以在afterFind中过滤掉它,但是如果Basket_id为null,我宁愿看到结果数组中没有Basket。怎么办


使用CakePHP 2.3.6。

在关联中使用
类型
键强制进行内部联接,而不是默认的左联接

class Banana extends AppModel {
    public $belongsTo = array(
        'Basket' => array(
            'type'  => 'inner',
            'conditions' => array('Banana.basket_id = Basket.id')
        )
    );
}

文档:

由于模型使用左连接来检索具有belongsTo关系的相关模型数据,因此相关字段的值正是您在具有空外键值的select结果中得到的值—每列中都为空值

解决方案是从afterFind回调中的结果数组中筛选这些相关模型

//Banana model

public function afterFind($results, $primary = false){
   if (isset($results['Basket']) && $results['Basket']['id'] === null) {
      unset($results['Basket']);
   }
   if (isset($results[0])){
       foreach($results as $key => $value){
          if (isset($value['Basket']) && $value['Basket']['id'] === null){
             unset($results[$key]['Basket']);
          }
       }
   }

   //If you forget this, nothing will happen...
   return $results;
}

当然,您可能希望将其设置为
false
,而不是取消设置它,或者设置为空数组,但由于我发现在这方面没有约定,建议是最受欢迎的。

我创建了一个单元测试来检查这一点。如果进行内部联接,则结果集为空(与SQL中的结果集相同)。您可以在这里看到测试:我在答案中添加了条件,如果仍然不起作用,请发布正在生成的SQL查询。如果没有匹配项,则内部不会显示任何内容。我想他会认为不存在的关联不应该显示空列。@giuseppe“但如果Basket_id为空,我宁愿看到结果数组中没有Basket”,但是type=>internal也会隐藏香蕉