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

时间:2018-09-28 21:08:39

标签: php cakephp model-view-controller foreign-keys cakephp-3.0

我有下表:

  1. 用户:id,名称,...
  2. 课程:id,名称,knowledge_area_id,education_institution_id,...
  3. users_courses:user_id,course_id,...
  4. 知识区: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(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/..和控制器上的所有内容都是正确的,因此我有什么想法可以解决此问题?

2 个答案:

答案 0 :(得分:2)

您可以使用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

答案 1 :(得分:0)

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

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

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

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