CakePHP 3如何使用REST以正确的方式保存相关关联1:N?

Posted

技术标签:

【中文标题】CakePHP 3如何使用REST以正确的方式保存相关关联1:N?【英文标题】:CakePHP 3 how to save related association 1:N in the right way using REST? 【发布时间】:2019-02-20 23:16:24 【问题描述】:

请问如何在Cakephp3中使用REST保存相关数据?

以免假设我有以下关联命令可以有许多相关标签(请参见下面的 EER 图)。

JSON 请求结构如下:


    "command": "whoami",
    "description": "SOMETHING",
    "public": false,
    "tags": [
        "name":"TEST1",
        "name":"TEST2"
    ]

我尝试使用

实现关联保存

https://book.cakephp.org/3.0/en/orm/saving-data.html#saving-with-associations

但没有运气。

所以我是按照以下方式进行的:

public function add()
    
        $this->request->allowMethod(['post']);
        $data = $this->request->getData();
        $user = $this->CommonHelper->getUserByToken($this->token);
        $command = $this->Commands->newEntity($data);
        $tags = $data['tags'];
        $command->user = $user;
        $command = $this->Commands->patchEntity($command, $data);
        if ($this->Commands->save($command)) 
            if($tags != null)
                $this->addTags($tags, $command);//TODO: DO IT IN THE RIGHT WAY WITH MARSHALLING
            $this->apiResponse['data'] = $command;
            $this->httpStatusCode = 200;
         else 
            $this->httpStatusCode = 400;
        
    

    private function addTags($tags, $command)
    
        foreach ($tags as $value) 
            $tag = $this->Tags->newEntity($value);
            $tag->commands_id = $command->id;
            $this->Tags->save($tag);
        
    

但这是唯一的临时解决方案,我想以正确的方式使用 CakePHP ORM 架构的可能性。

标签表定义如下:

public function initialize(array $config)
    
        parent::initialize($config);

        $this->setTable('tags');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');

        $this->belongsTo('Commands', [
            'foreignKey' => 'commands_id',
            'joinType' => 'INNER'
        ]);
    

感谢您的建议。

【问题讨论】:

您表明您的Tags 表与Commands 具有belongsTo 关联。但是Commands 是否与Tags 有对应的hasMany 关联? 不,它没有hasMany assoc。我认为在控制台中烘焙模型期间,应该根据 EER 方案(SQL 结构)自动添加这个 assoc。这意味着使用 $this->hasMany('Tags');我可以根据提供的 JSON 数据自动插入相关表吗? 您的架构不遵循CakePHP's naming conventions,外键应该是单数,因此烘焙无法正常工作。除非您明确指定不规则外键,否则手动添加的关联也不起作用。 谢谢,现在它可以开箱即用了。 【参考方案1】:

您可以通过这种方式保存相关数据。 您的数据数组应该是这种格式。

$data = array(
    "command"=> "whoami",
    "description"=> "SOMETHING",
    "public"> false,
    "tags": [
        array("name" => "TEST1"),
        array("name"=> "TEST2")
    ]
)

$patchedEntity= $this->Commands->patchEntity($saveData,$data,['associated' => ['Tags']]); 
$result = $this->Commands->save($patchedEntity);

在Commands表中定义关系应该是这样的。

public function initialize(array $config)
    
        parent::initialize($config); 
        $this->setTable('commands');  
        $this->hasMany('Tags', [
            'foreignKey' => 'command_id'
        ]);
    

标签表中的关系应该是这样的。

public function initialize(array $config)
    
        parent::initialize($config); 
        $this->setTable('tags');  
        $this->belongsTo('Commands', [
            'foreignKey' => 'command_id'
        ]);
    

【讨论】:

【参考方案2】:

它是由模型中的错误命名约定给出的。在外键中使用单数帮助我解决了这个问题。

【讨论】:

以上是关于CakePHP 3如何使用REST以正确的方式保存相关关联1:N?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CakePHP 3.x 中保存 belongsToMany 以进行编辑操作?

CakePHP 3.x 从实体获取相关数据

CakePHP - 如何在保存时将关联记录添加到模型中?

CakePHP 1.3 未保存到数据库但 sql 语句正确且 insertID 正确增加

在Cakephp 3.6中如何获取图像的大小和类型以通过表单发送?

CakePHP 3 REST API + CORS 请求和选项方法