php - CakePHP 3 保存 HasOne 关联

标签 php cakephp cakephp-3.0 cakephp-model

cakephp 框架中可能存在错误,但不确定

我得到了以下 MySQL InnoDB 表:

database.users
    +-----+---------------+----------+
    | id  | user_group_id | username |
    +-----+---------------+----------+
    | INT |           INT | VARCHAR  |

database.user_settings
    +-----+---------------+----------+
    | id  |       user_id |     data |
    +-----+---------------+----------+
    | INT |           INT |  VARCHAR |

我在表类中得到了以下初始化:

  • 模型\表\用户表:

    $this->table('users');
    $this->displayField('id');
    $this->primaryKey('id');
    $this->belongsTo('UserGroups', [
        'foreignKey' => 'user_group_id'
    ]);
    $this->hasOne('UserSettings', [
        'foreignKey' => 'user_id'
    ]);
    

  • 模型\表\UserSettingsTable

    $this->table('user_settings');
    $this->displayField('id');
    $this->primaryKey('id');
    $this->belongsTo('Users', [
        'foreignKey' => 'user_id'
    ]);
    
    // And folowing validation rules:
    $validator
        ->add('id', 'valid', ['rule' => 'numeric'])
        ->allowEmpty('id', 'create')
        // UserSettings.user_id validation rule:
        ->add('user_id', 'valid', ['rule' => 'numeric'])
        ->requirePresence('user_id', 'create')
        ->notEmpty('user_id');
    

    我得到了以下代码:

    $user = $this->Users->newEntity();
    if ($this->request->is('post')) {
        $user = $this->Users->patchEntity($user, $this->request->data, [
            'associated' => ['Users.UserSettings']
        ]);
        // Tried it also this way, won't change anything
        //$user = $this->Users->patchEntity($user, $this->request->data, [
        //  'associated' => ['user_setting']
        //]);
        $this->Users->save($user,['associated' => ['UserSettings']]);
    }
    

    示例输入数据($this->request->data):

    [
        'user_group_id' => 1, // Not related to question
        'username' => 'test', // This will be saved without core modifications
        'user_setting' => [
            'data' => 'sample data' // Saved only after "fix" described below
        ]
    ];
    

    这将保存父表(users),但不会保存子表(user_settings)。

    然后我得到了以下我想删除的修改:

    如果我将此更改放入 ORM\Associations\HasOne::saveAssociated(...)

    // $this->property() == 'user_setting'
    if (is_array($targetEntity)) {
        $targetEntity = $this->target()->newEntity($targetEntity);
    }
    

    它会立即按照我想要的方式工作。 HasOne 实际上具有所需的数据,但它还会检查数据是否在实体内部,在本例中它位于数组中。

    我尝试过不同的关联命名组合,看起来应该是这样的。

    主要问题是我应该如何保存可选的 hasOne 与父行的关联?

    我可以以某种方式确保数据将转换为实体对象吗? 我认为它应该可以正常工作,因为所有必需的数据都可用,而且它似乎也可以正确处理关系。

  • 最佳答案

    在@ndm提供的帮助下,我设法使用自定义编码器解决了这个问题。

    我首先确实查看了单独的验证器,但对我来说,解决非常简单直接的问题似乎过于复杂和脆弱。

    我诚实的观点是,所有这些实际上都应该在框架核心内部以某种方式得到处理。

    使用自定义编码器解决所需的 fk:

    这样应该确保仅当通过用户创建 UserSettings 并且 user_settings.user_id 应随时可用时才会使用“自定义验证”。

    class UsersMarshaller extends Marshaller {
        protected function _validate($data, $options, $isNew) {
            $errors = parent::_validate($data, $options, $isNew);
            if ($isNew) {
                unset($errors['user_setting']['user_id']['_required']);
            }
            return $errors;
        }
    }
    

    UsersTable类中:

    public function marshaller() {
        return new UsersMarshaller($this);
    }
    

    原始问题中的实际错误:

    patchEntity(...) 调用参数有错误,即使这些参数所做的事情使它们看起来可能是正确的。 关联应该是这样的:['linked' => ['UserSettings']]。不是 Users.UserSettingsuser_setting

    关于php - CakePHP 3 保存 HasOne 关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28393995/

    相关文章:

    PHP - 如何在 CakePhp 中获取插入记录的 id

    php - cakephp 3 图片上传

    php - 在 MySQL 全文搜索中处理拼写错误的最佳方法

    php - AES 256 和 Base64 加密字符串在 iOS 8 上有效,但在 iOS 7 上被截断

    php - 如何从 cakePHP 中的不同 Controller 将数据插入表

    php - 如何做另一个 Action ,但仍然在 cakephp 的浏览器中显示相同的 url

    php - CakePHP:保存从 MySQL View 加载的模型

    php - 将 composer.json 放在 CakePHP 安装的根目录中

    cakephp - cakephp 3:如何在表单按钮中添加类?

    php - 在 CakePHP 3 中更新/插入关联表数据