2015-04-15 2 views
1

Это довольно стандартная вещь, которую я сделал, вероятно, 600 раз в CakePHP 2, но на всю жизнь я не могу ее получить для работы в CakePHP 3.«Через» связь с полями «foreign_key» и «model» в CakePHP 3

У меня есть Videos, Photos, Articles. У меня также есть Categories.

Все видео, фото и статьи могут принадлежать одной или нескольким категориям.

Целью текущей проблемы является вытягивание видеороликов под определенной категорией.

Итак, я попытался это:

// VideosTable 
$this->belongsToMany('Categories', [ 
    'joinTable' => 'categorized', 
    'className' => 'Categorized', 
    'foreignKey' => 'foreign_key', 
    'conditions' => [ 
     'Categorized.model' => 'Videos', 
    ] 
]); 

public function getTopVideosByCategory($categorySlug) 
{ 
    return $this->Categories->find('all') 
     ->where(['Categories.slug' => $categorySlug]) 
     ->contain([ 
      'Videos' => function ($q) { 
       return $q 
        ->limit(8) 
        ->contain([ 
         'Tags', 
         'Categories' // tried with and without this 
        ]) 
        ->order([ 
         'Videos.featured' => 'DESC', 
         'Videos.created' => 'DESC' 
        ]); 
      } 
     ]) 
     ->first(); 
} 

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Categorized.model' in 'where clause'

Я пытался несколько других способов, включая создание модели в объединения таблиц, и несколько других, но продолжают получать ошибки. Я пробовал с каждым вариантом и с ограниченным количеством вариантов. Я пробовал использовать фактический класс Table, и я попробовал псевдо-одно (например, «Категоризировано» выше).

Я должен предположить, что это довольно стандартный, но не может найти пример в книге, и я просто не могу заставить его работать.


Edit:

Я также попытался это:

//VideosTable 
public function initialize(array $config) 
{ 
    $this->belongsToMany('Categories', [ 
     'through' => 'Categorized', 
     'conditions' => [ 
      'Categorized.model' => $this->alias(), 
     ] 
    ]); 
} 

public function getTopVideosByCategory($categorySlug) 
{ 
    return $this->find('all') 
     ->matching('Categories', function ($q) use ($categorySlug) { 
      return $q 
       ->where(['Categories.slug' => $categorySlug]); 
     }) 
     ->contain([ 
      'Tags', 
      'Categories' 
     ]) 
     ->limit(8) 
     ->order([ 
      'Videos.featured' => 'DESC', 
      'Videos.created' => 'DESC' 
      ]) 
     ->first(); 
} 

Но получить эту ошибку:

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Categorized.model' in 'on clause'

+0

Как выглядит схема таблицы для категории? –

+0

Категорируется только 'id' (CHAR 36),' foreign_key' (CHAR 36), 'model' (VARCHAR 60),' category_id' (CHAR 36) – Dave

ответ

3

С видео и категорий не 1- 1 o n-1 (hasOne или принадлежит To), невозможно построить SQL-выражение, которое может включать con для другой таблицы. В этих случаях CakePHP реализует функцию matching(). Он работает аналогично contain(), но то, что он делает это с помощью внутреннего соединения, чтобы получить данные из внешних ассоциаций:

http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#filtering-by-associated-data

Вы также можете посмотреть в пример использования его здесь:

http://book.cakephp.org/3.0/en/tutorials-and-examples/bookmarks/intro.html#creating-the-finder-method

+0

После повторного чтения вашего вопроса я добавил еще один ответ, так как я думаю, что я misunderstood –

+0

Я не уверен, какой ответ новый, но я не могу ни работать, ни работать. Когда я пытаюсь использовать '-> matching', я получаю' Error: SQLSTATE [42S22]: Столбец не найден: 1054 Неизвестный столбец «Категоризация.model» в разделе «on». Нужно ли мне также использовать параметры '-> join()' вручную? Пример в книге приятный, но, похоже, это не то же самое, что и вытягивание из связанной модели (я полагаю). В этом случае, хотя я сказал, что хочу использовать «Категоризированный» как «сквозную» модель, он говорит, что они не связаны. И когда я пытаюсь выполнить '-> where()' on Videos, это также вызывает ошибки. – Dave

+0

Я обновил свой вопрос с моей последней попыткой, основанной на обоих советах и ​​прочитав разделы предлагаемой книги. Я все еще ничего не понимаю. – Dave

0

Казалось, что вы хотите:

$this->belongsToMany('Categories', [ 
    'through' => 'Categorized', 
    'conditions' => ['Categorized.model' => $this->alias()] 
]); 
1

я в конечном итоге получить его работать так:

class VideosTable extends Table 
{ 
    public function initialize(array $config) 
    { 
     $this->hasMany('Categorized', [ 
      'foreignKey' => 'foreign_key', 
      'conditions' => [ 
       'Categorized.model' => $this->alias(), 
      ] 
     ]); 
    } 

    public function getTopVideosByCategory($categorySlug) 
    { 
     return $this->find() 
      ->matching(
       'Categorized.Categories', function ($q) use ($categorySlug) { 
        return $q 
         ->where(['Categories.slug' => $categorySlug]); 
      }) 
      ->limit(8) 
      ->order([ 
       'Videos.featured' => 'DESC', 
       'Videos.created' => 'DESC' 
       ]) 
      ->all(); 
    } 

я вверх проголосовал ответ Хосе, как это привело меня на путь выяснить это, но отметит это как ответ, как я думаю, что это более-быстро помогает пользователям попытаться понять эту проблему.

José, если вы хотите добавить это (с любыми настройками, которые вы сочтете нужными) к вашему ответу, я поменяю выделенный ответ на ваш.