我有一个相当简单的查询,根据是否指定要选择的字段,根据包含的字段生成不同的SQL语句。我知道这很混乱,所以我会尝试用代码描述问题。
我设置了以下关联,它们可以使用简单的find()
正常工作,但在我尝试使用find()->select
时却无法正常工作。
CollectionsTable:
$this->belongsTo('IconMedia', [
'foreignKey' => 'icon_media_id',
'className' => 'Media'
]);
$this->belongsTo('HeroMedia', [
'foreignKey' => 'hero_media_id',
'className' => 'Media'
]);
MediaTable:
$this->hasMany('CollectionsIconMedia', [
'foreignKey' => 'icon_media_id',
'className' => 'Collections'
]);
$this->hasMany('CollectionsHeroMedia', [
'foreignKey' => 'hero_media_id',
'className' => 'Collections'
]);
查询的完整简单版本,它返回所有字段,包括关联表HeroMedia
和IconMedia
的字段。
$this->Collections->find()
->contain(['Participations', 'HeroMedia', 'IconMedia']);
产生
SELECT Collections.id AS `Collections__id`,
Collections.name AS `Collections__name`,
Collections.slug AS `Collections__slug`,
Collections.description AS `Collections__description`,
Collections.icon_media_id AS `Collections__icon_media_id`,
Collections.hero_media_id AS `Collections__hero_media_id`,
Collections.user_id AS `Collections__user_id`,
Collections.created AS `Collections__created`,
Collections.modified AS `Collections__modified`,
HeroMedia.id AS `HeroMedia__id`,
HeroMedia.file AS `HeroMedia__file`,
HeroMedia.description AS `HeroMedia__description`,
HeroMedia.caption AS `HeroMedia__caption`,
HeroMedia.source AS `HeroMedia__source`,
IconMedia.id AS `IconMedia__id`,
IconMedia.file AS `IconMedia__file`,
IconMedia.description AS `IconMedia__description`,
IconMedia.caption AS `IconMedia__caption`,
IconMedia.source AS `IconMedia__source`
FROM collections Collections
LEFT JOIN media HeroMedia ON HeroMedia.id = (Collections.hero_media_id)
LEFT JOIN media IconMedia ON IconMedia.id = (Collections.icon_media_id)
这正是我所期待的。但是,我想限制从collection
表返回的选定字段。我尝试了以下声明:
$this->Collections->find()
->select( [ 'id', 'name', 'slug', 'description', 'icon_media_id', 'hero_media_id' ] )
->contain(['Participations', 'HeroMedia', 'IconMedia']);
遗憾的是,这会生成以下SQL。请注意,JOIN
仍然存在,但SELECT
和HeroMedia的IconMedia
已消失。
SELECT Collections.id AS `Collections__id`,
Collections.name AS `Collections__name`,
Collections.slug AS `Collections__slug`,
Collections.description AS `Collections__description`,
Collections.icon_media_id AS `Collections__icon_media_id`,
Collections.hero_media_id AS `Collections__hero_media_id`
FROM collections Collections
LEFT JOIN media HeroMedia ON HeroMedia.id = (Collections.hero_media_id)
LEFT JOIN media IconMedia ON IconMedia.id = (Collections.icon_media_id)
可能虚拟表HeroMedia
和IconMedia
存在问题(不确定它们的CakePHP名称是否正确),但它们似乎适用于简单的find()
而没有->select
。我试过阅读Query Builder和Associations文档,但没有找到任何解释这种现象的内容。
答案 0 :(得分:1)
您需要在所有字段上使用Table::aliasField()。
->contain([
$this->aliasField('name'),
'OtherTable.field',
'YetAnotherTable.field'
]);