这是一个非常标准的事情,我在CakePHP 2中已经完成了600次,但对于我的生活,我无法在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();
}
错误:SQLSTATE [42S22]:找不到列:1054未知列 'where子句'中的'Categorized.model'
我尝试过其他一些方法,包括创建连接表的模型和其他一些方法,但不断收到错误。我已尝试过每个选项,并且选项数量有限。我尝试过使用一个实际的Table类,我尝试过伪类(如上面的“Categorized”)。
我必须假设这是非常标准的,但在书中找不到一个例子,我似乎无法让它工作。
修改
我也试过这个:
//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();
}
但是得到这个错误:
错误:SQLSTATE [42S22]:找不到列:1054未知列 'on clause'中的'Categorized.model'
答案 0 :(得分:3)
由于视频和类别不是1-1 o n-1(hasOne或belongsTo),因此无法构建可包含其他表条件的SQL表达式。对于这些情况,CakePHP实现了matching()
函数。它与contain()
类似,但它的作用是使用INNER联接从外部关联中获取数据:
http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#filtering-by-associated-data
您还可以在此处查看使用它的示例:
答案 1 :(得分: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é的答案进行了投票,因为它让我走上了解决问题的道路,但我会将此作为答案,因为我认为它更快 - 帮助用户试图解决这个特定问题。< / p>
José,如果你想将这个(你认为合适的任何调整)附加到你的答案中,我会将你的标记答案改为你的。
答案 2 :(得分:0)
看起来你想要的是:
$this->belongsToMany('Categories', [
'through' => 'Categorized',
'conditions' => ['Categorized.model' => $this->alias()]
]);