【发布时间】:2021-03-13 13:17:01
【问题描述】:
我目前正在使用 CakePHP 为我编写的一些票务逻辑提供基于 crud 的 API。我遇到了一个问题,我试图更改新关联中的 belongsTo 关联和数据,但它没有持续存在。
执行持久化的控制器如下所示:
<?php
class TasksController extends Cake\Controller\Controller
{
public function initialize()
{
parent::initialize();
}
public function edit(array $ids): void
{
$validationErrors = [];
$tasks = $this->Tasks->find('all')
->contain($this->setAssociations($query))
->where([$this->Model->getAlias().'.id IN' => $ids]);
foreach ($tasks as $id => $task) {
$this->Tasks->patchEntity($task, $this->request->getQuery()[$id], [
'associated' => ['Asset']
]);
}
if ($this->Tasks->saveMany($tasks)) {
$this->response = $this->response->withStatus(200);
} else {
// Handle errors
}
// Render json output for success / errors
$this->set($this->createViewVars(['entities' => $tasks], $validationErrors));
}
}
任务表中资产的关联如下所示:
<?php
class TasksTable extends Cake\ORM\Table
{
public function initialize(array $config)
{
$this->belongsTo('Asset', [
'className' => 'Assets',
'foreignKey' => 'asset_id',
'joinType' => 'LEFT'
]);
}
}
这些构建规则附加到资产表中:
<?php
class AssetsTable extends Cake\ORM\Table
{
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['number', 'group_id'], 'The Number you selected is in use'));
$rules->add($rules->isUnique(['name', 'group_id'], 'The Name you selected is in use'));
}
}
我发送的请求正文如下所示:
{
"421933": {
"description": "This task was edited by the api!",
"asset": {
"id": "138499",
"description": "This asset was edited by they api!",
"name": "105",
"number": "6"
}
}
}
基本上,名称 105 和编号 6 被标记为不唯一,因为它们已经设置为资产 138499 上的那些值。查询是尝试将名称 105 和编号 6 编辑到当前的资产实体中与触发 isUnquie 构建规则失败的任务实体 (645163) 相关联。
您可以通过在上述控制器中的 saveMany 调用之前打印 $tasks 来看到这一点:
Array
(
[0] => App\Model\Entity\Task Object
(
[id] => 421933
[description] => This task was edited by the api!
.....
[asset] => App\Model\Entity\Asset Object
(
[id] => 645163
[name] => 105
[description] => This asset was edited by they api!
[number] => 6
....
)
)
)
似乎将资产 138499 作为任务 421933 的关联进行编辑应该可以工作,因为在 CakePHP 文档中似乎可以以这种方式保存 belongsTo 关联,如 here 所记录的那样:
<?php
$data = [
'title' => 'First Post',
'user' => [
'id' => 1,
'username' => 'mark'
]
];
$articles = TableRegistry::getTableLocator()->get('Articles');
$article = $articles->newEntity($data, [
'associated' => ['Users']
]);
$articles->save($article);
是否可以关联一个 belongsTo 关联并在同一个事务中对其进行编辑?如果是这样,我的请求或代码的结构应该如何不同?
谢谢!
【问题讨论】:
-
我会在修补实体后开始调试它们,这可能会泄露一些线索。顺便说一句,还有
patchEntities()用于一次修补多个实体。附言。您的saveMany()调用似乎只引用了最后一个实体,这看起来是错误的,应该使保存根本不起作用 - 请确保在此处发布代码时您没有过多地修改代码(如果有的话),因为可能会隐藏可能的问题! -
@ndm 好的,我想我知道发生了什么。当有另一个资产 645163 分配给它时,我试图将资产 138494 分配给任务,并在同一个调用中编辑值。 saveMany 试图覆盖资产 645163 的值上的名称和编号字段,而不是用资产 138494 替换它,这会触发 isunique 约束。因此,我发布的第四段代码中的主体没有正确触发 138494 分配给任务。看起来这应该是可能的,查看文档:book.cakephp.org/3/en/orm/…
-
但该标题是为 hasMany 关系指定的。我需要为 belongsTo 做不同的事情吗?我根据您的建议更新了答案中的代码,谢谢!
-
这对我来说听起来有点太抽象了,没有看到确切的数据/实体,但是 AFAIR,链接 1:1 关联记录(你没有
hasMany关联)和编辑它同时不起作用,因为编组器只会合并数据,而它必须加载新记录,替换现有实体,并将数据合并到新实体中才能正常工作。跨度> -
知道你在说什么当然不会有什么坏处;)你的关联已经是
belongsTo,所以我不确定你所说的“改变是什么意思“那个?
标签: php api cakephp orm cakephp-3.0