如何使用外键 CakePHP 显示另一个表中的数据?



我有以下表格:

  1. 用户: ID, 姓名, ...
  2. 课程: ID, 姓名, knowledge_area_id, educational_institution_id, ...
  3. users_courses: user_id, course_id, ...
  4. knowledge_areas:ID、姓名
  5. educational_institutions:ID,姓名,...

我目前正在尝试在用户的视图上显示有关该用户的一些信息,包括与他们相关的每门课程。这是我目前正在做的事情:

/Template/Users/view.ctp

<?php foreach($user->courses as $courses): ?>
<?= h($courses->name) ?>
<?= h($courses->knowledge_area_id) ?>
<?= h($courses->educational_institution_id ?>
<?= h($courses->description) ?>
<?php endforeach; ?>

这将显示与用户相关的每个课程及其名称、知识领域 ID、教育机构 ID 和课程描述。但是,我想显示知识领域的名称和教育机构的名称,而不是他们的ID。我试过做$courses->knowledge_area->name但它说我正在尝试从非对象获取属性name

当我尝试debug($courses)时,我得到:

object(AppModelEntityCourse) {
'id' => (int) 2,
'name' => 'course name',
'knowledge_area_id' => (int) 1,
'educational_institution_id' => (int) 1,
'description' => 'course description',
'_joinData' => object(CakeORMEntity) {
...
}

当在现实中我应该得到

object(AppModelEntityCourse) {
'id' => (int) 2,
'name' => 'course name',
'knowledge_area_id' => (int) 1,
'educational_institution_id' => (int) 1,
'description' => 'course description',
'educational_institution' => object(AppModelEntityEducationalInstitution) {
'id' => (int) 1,
'address_id' => (int) 1,
'name' => 'ed institution name',
'[new]' => false,
'[accessible]' => [
'address_id' => true,
'name' => true,
'address' => true,
'courses' => true,
'users' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'EducationalInstitutions'
},
'knowledge_area' => object(AppModelEntityKnowledgeArea) {
'id' => (int) 1,
'name' => 'knowledge area name',
'[new]' => false,
'[accessible]' => [
'name' => true,
'courses' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'KnowledgeAreas'
},
...
}

这样,我将能够使用$courses->knowledge_area->name,这基本上就是/Template/Courses/view.ctp上发生的事情,对于每门课程,我都能够显示它与哪个知识领域相关。

由于我遵循蛋糕约定并且我仔细检查了文件,因此我假设/Model/Table/..和控制器上的所有内容都是正确的,因此关于我可以做些什么来解决此问题的任何想法?

您可以使用contain()加载任意深度的关联:

$query = $products->find()->contain([
'Shops.Cities.Countries',
'Shops.Managers'
]);

看这里: https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#eager-loading-associations-via-contain

在玛丽的评论的帮助下,我设法找到了一个对我有用的稍微不同的解决方案。

由于我尝试编辑用户视图,因此我进入了用户控制器上的视图功能并更改了

$user = $this->Users->get($id, [ 'contain' => ['Addresses', 'AccessLevels', 'Courses', 'EducationalInstitutions' ] ]);

$user = $this->Users->get($id, [ 'contain' => ['Addresses', 'AccessLevels', 'Courses', 'EducationalInstitutions', 'Courses.KnowledgeAreas', 'Courses.EducationalInstitutions' ] ]);