CakePHP 3 更新连接表中的数据
Posted
技术标签:
【中文标题】CakePHP 3 更新连接表中的数据【英文标题】:CakePHP 3 updating data in the join table 【发布时间】:2016-12-11 22:35:33 【问题描述】:我在更新联接表中的现有数据时遇到问题。就这样吧……
我有 2 个模型 SalesOrders 和 Products,它们通过 LineItems 具有 belongsToMany 关联。
products
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| name | int(11) | NO | | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
sales_orders
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| order_number | int(11) | NO | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
line_items
+----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| sales_order_id | int(11) unsigned | NO | | NULL | |
| product_id | int(11) unsigned | NO | | NULL | |
| qty | int(11) | NO | | NULL | |
+----------------+---------------------+------+-----+---------+----------------+
按预期创建新的销售订单。我可以在添加新销售订单页面上向销售订单添加多个产品和数量。所有正确的数据都添加到连接表中。
我遇到的问题是当我尝试编辑现有销售订单时。例如,我想将某个行项目的数量从 5 更改为 2。我打开要修改的销售订单的编辑页面,更改所需行项目的数量,然后提交表单。表单提交成功,但连接表未更新。这似乎是我无法使用的非常基本的功能。我的所有代码都经过了一些小的修改。
SalesOrdersTable:
$this->belongsToMany('Products', [
'foreignKey' => 'sales_order_id',
'targetForeignKey' => 'product_id',
'through' => 'LineItems',
]);
产品表:
$this->belongsToMany('SalesOrders', [
'foreignKey' => 'product_id',
'targetForeignKey' => 'sales_order_id',
'through' => 'LineItems',
]);
LineItemsTable:
$this->belongsTo('Products', [
'foreignKey' => 'product_id',
'joinType' => 'INNER'
]);
$this->belongsTo('SalesOrders', [
'foreignKey' => 'sales_order_id',
'joinType' => 'INNER'
]);
SalesOrdersController 编辑:
public function edit($id = null)
$salesOrder = $this->SalesOrders->get($id, [
'contain' => ['Products']
]);
if ($this->request->is(['patch', 'post', 'put']))
$salesOrder = $this->SalesOrders->patchEntity($salesOrder, $this->request->data);
if ($this->SalesOrders->save($salesOrder))
$this->Flash->success(__('The sales order has been saved.'));
return $this->redirect(['action' => 'index']);
else
$this->Flash->error(__('The sales order could not be saved. Please, try again.'));
$products = $this->SalesOrders->Products->find('list', ['limit' => 200]);
$this->set(compact('salesOrder', 'products'));
$this->set('_serialize', ['salesOrder']);
SalesOrders 模板编辑.ctp
echo $this->Form->input('order_number');
echo $this->Form->input('products.0.id', [
'type' => 'select',
'options' => $products
]);
echo $this->Form->input('products.0._joinData.qty');
在提交表单以将数量从 5 更改为 2 时,SalesOrder 实体如下所示。
object(App\Model\Entity\SalesOrder)
'id' => (int) 1,
'order_number' => 'SO1111',
'products' => [
(int) 0 => object(App\Model\Entity\Product)
'id' => '1',
'name' => 'Acme Widget 1',
'_joinData' => object(App\Model\Entity\LineItem)
'id' => (int) 1,
'product_id' => (int) 1,
'sales_order_id' => (int) 1,
'qty' => (int) 2,
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'qty' => true
],
'[original]' => [
'qty' => (int) 5
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'LineItems'
,
'[new]' => false,
'[accessible]' => [
'*' => true,
'_joinData' => true
],
'[dirty]' => [
'_joinData' => true
],
'[original]' => [
'_joinData' => object(App\Model\Entity\LineItem)
'id' => (int) 1,
'product_id' => (int) 1,
'sales_order_id' => (int) 1,
'qty' => (int) 2,
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'qty' => true
],
'[original]' => [
'qty' => (int) 5
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'LineItems'
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Products'
],
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'SalesOrders'
如您所见,SalesOrder 上的脏属性为空。 Products _joinData 已被修改并没有发现。
如果我添加 $salesOrders->dirty('products', true);就在调用 save() 之前,连接表被更新。虽然这可行,并且我可以编写一些逻辑来以这种方式处理更新,但我觉得有更好/正确的方法来做到这一点。
任何帮助表示赞赏,在此先感谢。
【问题讨论】:
【参考方案1】:原来这是 3.3 中的一个蛋糕错误,直到 3.3.2 版本才解决。一旦我更新了一切都按预期工作。 github.com/cakephp/cakephp/pull/9276
【讨论】:
以上是关于CakePHP 3 更新连接表中的数据的主要内容,如果未能解决你的问题,请参考以下文章