CakePHP 3更新连接表中的数据

时间:2016-12-11 22:35:33

标签: cakephp cakephp-3.x

我在连接表中更新现有数据时遇到问题。这就是......

我有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',
]);

ProductsTable:

$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模板edit.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');

在提交表单时,SalesOrder实体看起来像这样,将数量从5更改为2。

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上的脏属性为空。它没有发现产品_joinData已被修改。

如果我添加$ salesOrders-> dirty('products',true);就在调用save()之前,连接表会更新。虽然这有效,但我可以编写一些逻辑来以这种方式处理更新,但我觉得有更好/正确的方法来做到这一点。

提前感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

原来这是3.3中的蛋糕错误,直到3.3.2版本才解决。一旦我更新了一切按预期工作。 github.com/cakephp/cakephp/pull/9276