Cakephp 3-BelongTomany association中的附加ID字段';这张桌子怎么了

Cakephp 3-BelongTomany association中的附加ID字段';这张桌子怎么了,cakephp,orm,cakephp-3.x,Cakephp,Orm,Cakephp 3.x,我一直在从事一个CakePHP3项目,该项目的某些部分比较复杂,而且该框架的官方文档似乎没有给出我想要的答案。需要做以下几件事: 用户可以属于多个项目。在每个项目中,属于当前项目的每个用户都可以访问应用程序的不同部分,这由一个名为Resources的表处理,该表存储资源ID 简言之,用户A可以访问项目A和项目B中不同数量的资源 我建立了以下关联: 通过UsersProjects属于任何项目的用户 用户通过UsersResources拥有任何资源 在users_resources-table I中

我一直在从事一个CakePHP3项目,该项目的某些部分比较复杂,而且该框架的官方文档似乎没有给出我想要的答案。需要做以下几件事:

用户可以属于多个项目。在每个项目中,属于当前项目的每个用户都可以访问应用程序的不同部分,这由一个名为Resources的表处理,该表存储资源ID

简言之,用户A可以访问项目A和项目B中不同数量的资源

我建立了以下关联:

  • 通过UsersProjects属于任何项目的用户
  • 用户通过UsersResources拥有任何资源
  • 在users_resources-table I中有以下字段:

    用户id |资源id |项目id

    project_id-字段被添加到表中,以使用户的资源特定于项目

    关联配置如下:

            $usersTable = TableRegistry::get('Users');
            $user = $usersTable->get(129);
            $data = [
                'resources' => [
                    [
                        'id' => 48,
                        '_joinData' => [
                            'project_id' => 2
                        ]
                    ]
                ]
            ];
            $user = $usersTable->patchEntity($user, $data, ['associated' => ['Resources']]);
            if ($usersTable->save($user)) {
                $this->out('success');
            } else {
                $this->out('fail');
            }
    
       {
            "id": 129,
            "email": "john.doe@example.com",
            "created": null,
            "modified": "2016-02-05T20:50:06+0000",
            "firstname": "John",
            "lastname": "Doe",
            "type": 1,
            "resources": [
                {
                    "id": 48,
                    "type": "r",
                    "_joinData": {
                        "project_id": 2
                    }
                }
            ]
        }
    
    用户稳定:

            $this->belongsToMany('Resources', [
                'foreignKey' => 'user_id',
                'targetForeignKey' => 'resource_id',
                'joinTable' => 'users_resources',
                'through' => 'UsersResources'
            ]);
    
    资源稳定:

            $this->belongsToMany('Users', [
                'foreignKey' => 'resource_id',
                'targetForeignKey' => 'user_id',
                'joinTable' => 'users_resources',
                'through' => 'UsersResources'
            ]);
    
            $this->belongsTo('Users', [
                'foreignKey' => 'user_id',
                'joinType' => 'INNER'
            ]);
    
            $this->belongsTo('Resources', [
                'foreignKey' => 'resource_id',
                'joinType' => 'INNER'
            ]);
    
            $this->belongsTo('Projects', [
                'foreignKey' => 'project_id',
                'joinType' => 'INNER'
            ]);
    
    UsersResourcesTable:

            $this->belongsToMany('Users', [
                'foreignKey' => 'resource_id',
                'targetForeignKey' => 'user_id',
                'joinTable' => 'users_resources',
                'through' => 'UsersResources'
            ]);
    
            $this->belongsTo('Users', [
                'foreignKey' => 'user_id',
                'joinType' => 'INNER'
            ]);
    
            $this->belongsTo('Resources', [
                'foreignKey' => 'resource_id',
                'joinType' => 'INNER'
            ]);
    
            $this->belongsTo('Projects', [
                'foreignKey' => 'project_id',
                'joinType' => 'INNER'
            ]);
    
    UsersResourcesTable类中还实现了一个buildRules函数,用于帮助实现数据完整性:

      public function buildRules(RulesChecker $rules)
        {
            $rules->add($rules->existsIn(['user_id'], 'Users'));
            $rules->add($rules->existsIn(['resource_id'], 'Resources'));
            $rules->add($rules->existsIn(['project_id'], 'Projects'));
            $rules->add($rules->isUnique(['user_id', 'resource_id', 'project_id']));
            return $rules;
        }
    
    数据按如下方式保存:

            $usersTable = TableRegistry::get('Users');
            $user = $usersTable->get(129);
            $data = [
                'resources' => [
                    [
                        'id' => 48,
                        '_joinData' => [
                            'project_id' => 2
                        ]
                    ]
                ]
            ];
            $user = $usersTable->patchEntity($user, $data, ['associated' => ['Resources']]);
            if ($usersTable->save($user)) {
                $this->out('success');
            } else {
                $this->out('fail');
            }
    
       {
            "id": 129,
            "email": "john.doe@example.com",
            "created": null,
            "modified": "2016-02-05T20:50:06+0000",
            "firstname": "John",
            "lastname": "Doe",
            "type": 1,
            "resources": [
                {
                    "id": 48,
                    "type": "r",
                    "_joinData": {
                        "project_id": 2
                    }
                }
            ]
        }
    
    修补实体后的实体数据:

            $usersTable = TableRegistry::get('Users');
            $user = $usersTable->get(129);
            $data = [
                'resources' => [
                    [
                        'id' => 48,
                        '_joinData' => [
                            'project_id' => 2
                        ]
                    ]
                ]
            ];
            $user = $usersTable->patchEntity($user, $data, ['associated' => ['Resources']]);
            if ($usersTable->save($user)) {
                $this->out('success');
            } else {
                $this->out('fail');
            }
    
       {
            "id": 129,
            "email": "john.doe@example.com",
            "created": null,
            "modified": "2016-02-05T20:50:06+0000",
            "firstname": "John",
            "lastname": "Doe",
            "type": 1,
            "resources": [
                {
                    "id": 48,
                    "type": "r",
                    "_joinData": {
                        "project_id": 2
                    }
                }
            ]
        }
    
    当使用项目id 2保存数据时,保存将按预期进行。当我保存相同的数据但将项目id更改为1(用户id和资源id将保持不变)时,将从表中删除项目id为2的前一行。期望的行为显然是旧记录将保留在表中。不过我注意到,在UsersTable的资源关联定义中添加一个值为“append”的saveStrategy选项将使保存正确进行(不会删除具有project_id 2的行)。但是,当我尝试在使用append策略时保存现有记录时,保存将失败(保存结果为false)

    因此,如果使用替换策略,先前的数据将被删除,如果使用追加策略,现有行的更新将导致cake透视图中的错误。我认为这个错误是在规则检查期间由于唯一的规则而抛出的

    我认为替换策略是可行的,但似乎忽略了project_id-field值,这会导致在使用不同的project_id添加新行时删除以前的数据(具有相同的用户_id和资源_id)

    所以我的问题是:

    是否可以将第三个id字段添加到BelongToMany association的槽表中,这样额外的字段也会被视为id字段,以便框架知道何时更新或向联接表插入记录

    这个想法是表中的所有三个字段都是唯一的。现在,框架似乎丢弃了额外的字段,因此插入和更新无法按预期工作。或者数据库结构中是否存在需要修复的设计缺陷


    我更愿意坚持CakePHP约定,但这种情况似乎很难解决。感谢您的指导

    “放弃”和“不起作用”到底是什么意思?您的实际关联配置是什么样子的?您如何保存数据?数据是什么样子的?你明白了吗?我用你要求的信息编辑了这个问题,希望它能帮助你弄清楚到底发生了什么