使用额外字段保存 HABTM


Saving HABTM with extra fields?

我正在尝试保存订单和订单中的产品。

订单正在保存,但产品未保存。

我有一个orders桌和一个products桌和一个orders_products桌。

在我设置的订单模型中$hasAndBelongsToMany = 'Product';

orders_products表上,我有几个额外的字段:order_idproduct_id加上pricequantity捕获销售价格和销售数量。

我通过以下方式保存数据:

$this->订单>全部保存($data(;

以下是$data:

Array
(
    [Order] => Array
        (
            [user_email] => st@kr.com
            [billing_first] => Steve
            ... //more excluded
            [total] => 5000
        )
    [Product] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [price] => 5000.00
                    [quantity] => 1
                )
        )
)
订单将保存到

订单表中,但不会将任何内容保存到orders_products表中。我预计orders_products表可以节省[new_order_id], 1, 5000.00, 1

我确实收到此通知:

Notice (8): Undefined index: id [CORE/cake/libs/model/model.php, line 1391]
Model::__saveMulti() - CORE/cake/libs/model/model.php, line 1391
Model::save() - CORE/cake/libs/model/model.php, line 1355
Model::__save() - CORE/cake/libs/model/model.php, line 1778
Model::saveAll() - CORE/cake/libs/model/model.php, line 1673
CartsController::saveOrder() - APP/controllers/carts_controller.php, line 128
CartsController::checkout() - APP/controllers/carts_controller.php, line 172
Dispatcher::_invoke() - CORE/cake/dispatcher.php, line 204
Dispatcher::dispatch() - CORE/cake/dispatcher.php, line 171
[main] - APP/webroot/index.php, line 83

有什么想法吗?

HABTM 超卖。很多时候它无法满足需求,例如当您有额外的数据要存储时。你最好在模型之间做一个有/属于的关系。

摘自 CakePHP Book:

当HABTM成为时该怎么办 复杂?

默认情况下,保存 拥有和属于许多关系,蛋糕 将删除连接表上的所有行 在保存新的之前。例如,如果 您有一个有 10 名儿童的俱乐部 相关。然后,您更新俱乐部 带着2个孩子。俱乐部只会 有2个孩子,而不是12个。

另请注意,如果要添加更多 联接字段(当它是 创建或元信息(这是 可以使用 HABTM 连接表,但是 重要的是要了解您 有一个简单的选择。

拥有和属于许多在两个模型之间 实际上是三个人的简写 通过两个 有很多,属于协会。

在您的情况下,我建议制作一个LineItem模型并以这种方式连接所有内容:

  • Order有很多LineItem
  • LineItem属于OrderProduct

HATBM以一种非常奇怪的方式工作。如果您确实需要 HATBM,我建议不要更改模型关联,而是使用一个有趣的速记来保存连接表中的其他数据字段。

我遇到过很多次,这是最好的解决方案:实际上,只是为了保存您的附加字段,您可以取消绑定所有 HATBM 关系和添加一个指向联接模型的新 hasMany 绑定"动态"。首先,您应该解除绑定现有的 HATBM 关系。

$this->Order->unbindModel(array('hasAndBelongsToMany' => array('Product')));

然后添加新的"即时"具有许多绑定:

$this->Order->bindModel(array('hasMany' => array('OrdersPost')));

然后,如果您的数据是:

$this->data['Order']['id'] = '1';
$this->data['OrdersPost'][0]['product_id'] = '15';
$this->data['PostsTag'][0]['price'] = '5000.00';
$this->data['PostsTag'][0]['quantity'] = '1';
$this->data['OrdersPost'][1]['product_id'] = '16';
$this->data['PostsTag'][1]['price'] = '4000.00';
$this->data['PostsTag'][1]['quantity'] = '2';

如上所述,HATBM 总是在插入新记录之前擦除所有现有记录。因此,也许您应该在这样做之前注意这一点:

$this->Order->saveAll($this->data);

当您不想更改数据模型但仍需要其他功能时,此方法有效。希望这有帮助。原始解决方案和信用在这里

我通常在使用 SaveAll 时遇到的另一个问题是它不会保存相关记录。在您的示例中,订单已保存,但订单产品(或订单项(未保存。我通常做的是这样的:

if ($this->Order->save($this->data)) {
    for($i=0; $i<sizeof($this->data['OrderProduct']); $i++){
        $this->data['OrderProduct'][$i]['order_id'] = $this->Order->id;
    }
    $this->Order->OrderProduct->saveAll($this->data['OrderProduct']);
}

这里发生的事情是首先保存订单,然后将其ID复制到每个订单产品。然后保存订单产品记录。

将其他数据保存在orders_products表中对我来说似乎不是一个好主意。如果订单有多个产品怎么办。您是否将每个条目的订单总额存储在orders_products表中?你为什么不把这些信息存储在Order里呢?这对我来说更有意义。

您的错误似乎来自损坏的数据模型。

您可以使用以前的解决方案,但如果还必须更新父表,则必须取消绑定。在我的示例中,我有一个表订单和一个表产品。我需要为每个产品添加两个关于 Order.id 的额外字段。请参阅此示例:

    $this->Order->create(); 
    $this->Order->unBindModel(array('hasAndBelongsToMany'=>array('Product')));
    $f  = $this->Order->save($this->data,false);
    /* Save extra columns in HABTM TABLE */
    $this->Order->bindModel(array('hasMany'=>array('OrderProduct')));
    $q = array();
    if (!isset($this->data['Product']))
    {
        $v  = false;
    }
    else
    {
        $v =true;
        for($i=0;$i<count($this->data['Product']);$i++)
        {
            $this->data['OrderProduct'][$i]['order_id']     = $this->Order->getLastInsertID();
            $this->data['OrderProduct'][$i]['product_id']   = $this->data['Product'][$i];
            $this->data['OrderProduct'][$i]['quantity']         = $this->data['quantity'][$i];
            $this->data['OrderProduct'][$i]['state_id']         = $this->data['State'][$i];
        }
    }
    $s  = $this->Order->OrderProduct->saveAll($this->data['OrderProduct']);

可能是您的orders_products表没有自己的主键。除非您的表看起来有些东西,否则您将收到此错误喜欢这个

CREATE TABLE orders_products (
  id integer,
  order_id integer,
  product_id integer,
  ...

我刚才才有同样的问题。对不起,这么简单的答案没有早点找到你。