2016-02-05 8 views
1

У меня ассоциация Price belongsTo Seasonсогласующих ассоциаций и не связана запись CakePHP 3

Я пытаюсь запросить все цены, которые соответствуют определенному диапазону дат, когда прошли в сезоне, а также любой, которые не имеют ни одного (Prices.season_id=0)

Вот что у меня есть:

// build the query 
$query = $this->Prices->find() 
    ->where(['product_id'=>$q['product_id']]) 
    ->contain(['Seasons']); 

if(!empty($to_date) && !empty($from_date)) { 
    $query->matching('Seasons', function ($q) { 
    return $q->where([ 
     'from_date <= ' => $to_date, 
     'to_date >= ' => $from_date 
    ]); 
    }); 
} 

Однако это будет возвращать только цены явно связанные с сезоном. Как мне заставить его возвращать Price.season_id = 0 также?

ответ

0

Внутренний вызов $query->matching() создает INNER JOIN и помещает where-statements функции обратного вызова в предложение ON соединения. Для извлечения элементов без ассоциации вам нужен LEFT JOIN. Так что ваш codesnippet будет выглядеть следующим образом:

if(!empty($to_date) && !empty($from_date)) { 
    $query->leftJoinWith('Seasons', function ($q){return $q;}); 
    $query->where([[ 
     'or' => [ 
      'Season.id IS NULL', 
      [ 
       'from_date <= ' => $to_date, 
       'to_date >= ' => $from_date, 
      ], 
     ], 
    ]]); 
} 

Таким образом, мы создаем нормальную INNER JOIN и разместить условия в нормальном() where самих дальнем от центра пункта запроса.

Двойной массив предназначен для смещения, возможно, другого, где условия с соединением or.

Я сам наткнулся на column IS NULL вместо 'column' => null синтаксис.

PS: Это работает для всех ассоциаций. Для hasMany и belongsToMany вам необходимо сгруппировать результаты с $query->group('Prices.id')