使用 CakePHP 3 中的其他关联创建与条件的关联

Creating Association with condition using other association in CakePHP 3

我正在制作蛋糕 php 3 个应用。我的应用程序模型包括 3 个表(以及其他表):

其中每个结构可以有多个测量点:

// StrcuturesTable.php
...
public function initialize(array $config)
{
    parent::initialize($config);

    ...

    $this->hasMany('MeasuringPoints', [
        'foreignKey' => 'structure_id'
    ]);
}

此外,每个测量点都是某种设备类型:

// MeasuringPointsTable.php
...
public function initialize(array $config)
{
    parent::initialize($config);
    ...
    $this->belongsTo('DeviceTypes', [
        'foreignKey' => 'device_type_id',
        'joinType' => 'INNER'
    ]);
}

我正在寻找的是如何在结构 table 中创建 'SpecialMeasuringPoints' 关联。

有点像:

// MeasuringPointsTable.php
...
    $this->hasMany('SpecialMeasuringPoints',[
            'className' => 'MeasuringPoints',
            'foreignKey' => 'structure_id',
            'conditions' => ['MeasuringPoints.DeviceTypes.id'=>1]
    ]);

如您所见,我只需要那些关联设备类型为 id 1 的测量点。 但是,先前的关联条件无效;我不知道如何正确地实现它。

感谢任何帮助。

正确,该条件无效,原因有很多。首先,根本不支持路径,即使支持,您已经分别在 MeasuringPointsSpecialMeasuringPoints 中,因此无需再次指出。

虽然可以传递如下条件:

'DeviceTypes.id' => 1

这将要求在检索 SpecialMeasuringPoints 时始终包含 DeviceTypes

我建议使用查找器,这样您就可以轻松地包含 DeviceTypes 并匹配您所需的条件。类似于:

$this->hasMany('SpecialMeasuringPoints',[
    'className' => 'MeasuringPoints',
    'foreignKey' => 'structure_id',
    'finder' => 'specialMeasuringPoints'
]);

在你的 MeasuringPoints class 中定义适当的查找器,例如使用 matching(),你应该很好:

public function findSpecialMeasuringPoints(\Cake\ORM\Query $query) {
    return $query
        ->matching('DeviceTypes', function (\Cake\ORM\Query $query) {
            return $query
                ->where([
                    'DeviceTypes.id' => 1
                ]);
        });
}

在传递回调时,可以通过 conditions 选项完成类似的操作,但它不那么干:

$this->hasMany('SpecialMeasuringPoints',[
    'className' => 'MeasuringPoints',
    'foreignKey' => 'structure_id',
    'conditions' => function (
            \Cake\Database\Expression\QueryExpression $exp,
            \Cake\ORM\Query $query
        ) {
            $query
                ->matching('DeviceTypes', function (\Cake\ORM\Query $query) {
                    return $query
                        ->where([
                            'DeviceTypes.id' => 1
                        ]);

            return $exp;
        }
]);

需要注意的是,在这两种情况下,您都需要注意此类构造与 cascading/dependent 删除不兼容,因此请勿尝试通过此类关联 unlink/delete!

另见