1

У меня есть модель, которая имеет отношение к отношению, которое не требуется.CakePHP: принадлежит с нулевым значением

Banana belongsTo Basket 
banana.basket_id can be null 

Это означает, что банан может принадлежать корзине, но это необязательно.

операция сохранения Banana->save(array('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. Что делать?

Использование CakePHP 2.3.6.

ответ

-1

Используйте ключ type в вашей ассоциации, чтобы включить соединение INNER вместо стандартного соединения LEFT.

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

Docs: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#belongsto

+0

Я создал единичный тест, чтобы проверить это. Если вы делаете INNER JOIN, вы получаете пустой набор результатов (то же, что и в SQL). Вы можете увидеть тест здесь: https://gist.github.com/dizyart/5892935 –

+0

Я добавил условия для своего ответа, если это все еще не работает, отправьте созданный SQL-запрос. – Costa

+1

INNER ничего не показывает, если нет совпадения. Я думаю, что он бы не существовал, чтобы ассоциация не отображала нулевые столбцы. – giuseppe

3

Поскольку модель использует LEFT JOIN для получения данных, относящихся к модели с belongsTo отношения, значения соответствующих полей именно то, что вы получите в отборной результат с нулевой внешней ключевое значение - нулевые значения в каждом столбце.

Решение заключается в фильтрации этих связанных моделей из массива результатов в обратном вызове 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 вместо неустановленного его, или, может быть пустой массив, но так как я не нашел конвенции по этому вопросу, предложения приветствуется.