问题描述
我有主表 portfolios
并且有 2 个子表 portfoliotags
和 p_snaps
型号如下
class PortfoliosTable extends Table
{
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('portfolios');
$this->setdisplayField('id');
$this->setPrimaryKey('id');
$this->hasMany('PSnaps',[
'foreignKey' => 'portfolio_id',]);
$this->hasMany('PortfolioTags',]);
}
}
class PortfolioTagsTable extends Table
{
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('portfolio_tags');
$this->setdisplayField('id');
$this->setPrimaryKey('id');
$this->belongsTo('Portfolios','joinType' => 'INNER',]);
$this->belongsTo('Tags',[
'foreignKey' => 'tag_id',]);
}
}
class PSnapsTable extends Table
{
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('p_snaps');
$this->setdisplayField('title');
$this->setPrimaryKey('id');
$this->belongsTo('Portfolios',]);
}
}
find()
控制器中的方法如下
$pfolios = $this->Portfolios->find('all')
->select(['Portfolios.id','Portfolios.client','Portfolios.country','Portfolios.url'])
->where(['Portfolios.status'=>1])
->order(['Portfolios.order_at'=>'asc','Portfolios.id'=>'asc'])
->limit(8)
->contain([
'PSnaps'=>function($q){
return $q
->select(['PSnaps.portfolio_id','PSnaps.snap'])
->where(['PSnaps.status'=>1])
->order(['PSnaps.order_at'])
->limit(1);
},'PortfolioTags.Tags'=>function($q2){
return $q2
->order(['Tags.tag']);
}
])
->toList();
debug($pfolios);exit;
它在 Portfolio 的第一条记录中重新调整 PSnaps,而在所有其他记录中它是空数组
虽然我知道数据库中有记录,但我也尝试在 MysqL 中使用以下查询
SELECT p.id,s.snap FROM `portfolios` p INNER join p_snaps s on p.id=s.portfolio_id
它返回的记录如下
id snap
1 s1.png
2人.png
3 gmap.png
4 ita.png
5 肥皂.png
6 聊天.png
7 aissmo.png
8 zippy.png
2 pereport.png
解决方法
这是因为limit()
里面有PSnaps
,如果被注释了会显示每个Portfolios记录下的所有PSnap记录。
为了处理这种情况,我通过在 hasOne
as 中添加 PortfoliosTable.php
关系来修复它
$this->hasOne('FirstPSnaps',[
'className' => 'PSnaps','foreignKey' => 'portfolio_id','strategy' => 'select','sort' => ['FirstPSnaps.order_at' => 'ASC'],'conditions' => function ($e,$query) {
return [];
}]);
现在控制器中的调用将更改为如下
$pfolios = $this->Portfolios->find('all')
->select(['Portfolios.id','Portfolios.client','Portfolios.country','Portfolios.url'])
->where(['Portfolios.status'=>1])
->order(['Portfolios.order_at'=>'asc','Portfolios.id'=>'asc'])
->limit(8)
->contain([
/********instead of PSnap I used FirstPSnaps *********/
'FirstPSnaps'=>function($q){
return $q
->select(['FirstPSnaps.portfolio_id','FirstPSnaps.snap'])
->where(['FirstPSnaps.status'=>1])
->order(['FirstPSnaps.order_at']);
},'PortfolioTags.Tags'=>function($q2){
return $q2
->order(['Tags.tag']);
}
])
->toList();
debug($pfolios);exit;