如何使用外键 CakePHP 显示来自另一个 table 的数据?

How to show data from another table with foreign key CakePHP?

我有以下表格:

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

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

/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(App\Model\Entity\Course) {

    'id' => (int) 2,
    'name' => 'course name',
    'knowledge_area_id' => (int) 1,
    'educational_institution_id' => (int) 1,
    'description' => 'course description',
    '_joinData' => object(Cake\ORM\Entity) {
    ...
}

实际上我应该得到

object(App\Model\Entity\Course) {

    'id' => (int) 2,
    'name' => 'course name',
    'knowledge_area_id' => (int) 1,
    'educational_institution_id' => (int) 1,
    'description' => 'course description',
    'educational_institution' => object(App\Model\Entity\EducationalInstitution) {

        '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(App\Model\Entity\KnowledgeArea) {

        '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

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

因为我试图编辑用户视图,所以我进入了用户控制器上的视图功能并进行了更改

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

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