【问题标题】:CakePHP Entity contain without foreign keyCakePHP 实体包含没有外键
【发布时间】:2015-05-15 04:07:33
【问题描述】:

我有一个实体别墅,我希望这个实体包含其他具有相同“复杂”的别墅 (Varchar(255))。

class VillasTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        $this->table('villas');
        $this->displayField('name');
        $this->primaryKey('id');

        $this->hasMany('Complexs', [
            'className' => 'Villas',
            'foreignKey' => false,
            'propertyName' => 'complexs',
            'conditions' => ['Complexs.complex' => 'Villas.complex']
        ]);
    }
}
?>

我不知道这是否可能。我不想在需要这些实体的每个函数中添加一个 find 。另外我想在使用这个新字段的实体中创建一个函数。 ``

【问题讨论】:

  • 那么问题出在哪里?
  • 在 cakePHP 3 中,我们不能使用 false 作为外键 :'(
  • 啊,再看,这是一个hasMany 关联,对,他们不支持禁用外键,因为 ORM 不知道如何收集键并将结果拼接在一起.
  • 我已经更新了我的答案,它缺少对主键的比较,以避免主记录包含在关联记录中。

标签: php cakephp foreign-keys cakephp-3.0


【解决方案1】:

尽管使用VARCHAR(255) 作为外键可能效率非常低和/或需要大量索引,但我想通常定义另一个表的外键的选项在这里会派上用场,类似到targetForeignKeybelongsToMany 关联。您可能想suggest that as an enhancement

结果格式化程序

目前这似乎无法使用关联开箱即用,因此您可能必须自己选择并注入关联的记录,例如在结果格式化程序中。

$Villas
    ->find()
    ->formatResults(function($results) {
        /* @var $results \Cake\Datasource\ResultSetInterface|\Cake\Collection\Collection */

        // extract the custom foreign keys from the results
        $keys = array_unique($results->extract('complex')->toArray());

        // find the associated rows using the extracted foreign keys
        $villas = \Cake\ORM\TableRegistry::get('Villas')
            ->find()
            ->where(['complex IN' => $keys])
            ->all();

        // inject the associated records into the results
        return $results->map(function ($row) use ($villas) {
            if (isset($row['complex'])) {
                // filters the associated records based on the custom foreign keys
                // and adds them to a property on the row/entity
                $row['complexs'] = $villas->filter(function ($value, $key) use ($row) {
                    return
                        $value['complex'] === $row['complex'] &&
                        $value['id'] !== $row['id'];
                })
                ->toArray(false);
            }
            return $row;
        });
    });

这将在之后使用自定义外键获取关联的行,并注入结果,以便您最终获得实体上的关联记录。

另见Cookbook > Database Access & ORM > Query Builder > Adding Calculated Fields

可能还有其他选项,例如使用自定义的 Eager loader 来收集必要的键,并结合使用适当的键将结果拼接在一起的自定义关联类,请参阅

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多