首页 > 解决方案 > CakePHP 4 - 对于表 A 中的 2 个外键,从表 B 中获取对应数据

问题描述

使用 CakePHP 4.1.6

我的数据库中有两个名为Categoriesand的表CategoryChanges。该Categories表很简单,因为它包含一个包含多个类别的 ID 和名称的列表,例如

id | name
------------
1  | Foo
------------
2  | Bar
------------
3  | Baz
------------

我的另一个表CategoryChanges是应用程序中的类别(如Categories)何时更改的日志,以及其他一些数据,例如谁更改了它们以及何时更改。

其中CategoryChanges有两列category_id_fromcategory_id_to它们对应于Categories.id

例如,CategoryChanges可能包括以下内容:

id | category_id_from | category_id_to | created    | user | notes 
--------------------------------------------------------------------
80 | 2                | 3              | 2021-02-03 | John | abcdef
--------------------------------------------------------------------
81 | 3                | 3              | 2021-03-15 | Jack | ghi
--------------------------------------------------------------------
82 | 1                | 2              | 2021-03-18 | Dave | zzz
--------------------------------------------------------------------

我想要做的是在网页上输出一个表格,显示上述信息,但我不想将category_id_fromandcategory_id_to作为数字 ID,而是希望Categories.name出现。请注意,对于某些行,“from”和“to”值也可能相同(例如,请参阅 参考资料CategoryChanges.id = 81)。

所以我想要的输出是这样的:

id | category_from | category_to | created    | user | notes 
--------------------------------------------------------------------
80 | Bar           | Baz         | 2021-02-03 | John | abcdef
--------------------------------------------------------------------
81 | Baz           | Baz         | 2021-03-15 | Jack | ghi
--------------------------------------------------------------------
82 | Foo           | Bar         | 2021-03-18 | Dave | zzz
--------------------------------------------------------------------

阅读查询生成器文档后,我看不到如何执行此操作。

我的假设是我需要从CategoryChanges简单的表格中读取:

// in a Controller method
$CategoryChanges = $this->getTableLocator->get('CategoryChanges');
$query = $CategoryChanges->find();

如果我执行$query->toArray(),我会得到上面的第二个表,其中包含 和 的数字category_id_fromID category_id_to

我认为$query“类别来自”和“类别至”需要额外的条件 - 或者可能是虚拟字段。我看不到如何将这两列连接起来Categories,以便Categories.name按照表 3 获得。

标签: phpcakephpcakephp-4.x

解决方案


belongsTo例如,您可以简单地将这些字段的两个关联添加到您的CategoryChanges表中,然后轻松地innerJoinWith()与您的查询一起使用,例如:

$this
    ->belongsTo('CategoryFrom')
    ->setClassName('Categories')
    ->setForeignKey('category_id_from');
    
$this
    ->belongsTo('CategoryTo')
    ->setClassName('Categories')
    ->setForeignKey('category_id_to');
$query = $CategoryChanges
    ->find()
    ->select([
        'id',
        'category_from' => 'CategoryFrom.name',
        'category_to' => 'CategoryTo.name',
        'created',
        'user',
        'notes',
    ])
    ->innerJoinWith('CategoryFrom')
    ->innerJoinWith('CategoryTo');

推荐阅读