0

我在 CakePHP 2 中有以下代码:

$this->Order->id = 5;
$this->Order->saveAll(array(
    'Order' => array(
        'person_id' => $this->Session->read('Person.id'),
        'amount' => $total,
        'currency_id' => $code                   
    ),
    'Lineitem' => $lineitems  /* a correctly-formatted array */
));

我希望这会更新Order表中主键为 5 的行,然后插入Lineitemorder_id 为 5 的行。

但是,它所做的只是在其中创建一个新行,Order然后使用新Order记录中的新 id 来创建Listitem行。

注意:我只是为了调试目的和轻松演示这个问题而设置上面的 ID。在我的最终代码中,我将检查当前是否已经存在挂单,person_id如果$this->Order->id = $var;有,$this->Order->create();是否没有。

换句话说,有时我会希望它插入(在这种情况下我会发出$this->Order->create();),有时我会希望它更新(在这种情况下我会发出$this->Order->id = $var;)。上面的测试用例应该产生一个 UPDATE 但它却产生了一个 INSERT。

知道我在这里做错了什么吗?

4

2 回答 2

3

您传递给的数组不Model->saveAll()包含订单的 id,因此 Cake 创建了一个新的。如果您想更新现有记录,您可以在传递的数组中设置订单 ID,或者使用查找来检索它。该文档明确指出

如果您想更新一个值,而不是创建一个新值,请确保您将主键字段传递到数据数组

$order = $this->Order->findById(5);
// ... modify $order if needed
$this->Order->saveAll(array('Order' => $order, 'LineItem' => $items));

在您的情况下,您可能希望尽可能简洁地使用以下内容。Model::saveAssociated()足够聪明,可以根据 来创建或更新id,但您必须提供合适的输入。Model::read($fields, $id)初始化 internal $data:对于现有记录,所有字段都将从数据库中读取,但对于不存在的 id,您需要提供正确的数据才能成功。假设订单belongsTo是客户,如果订单不存在,我会提供客户 ID

// set the internal Model::$data['Order']
$this->Order->read(null, 5);
// You may want to supply needed information to create
// a new order if it doesn't exist, like the customer
if (! $this->Order->exists()) {
    $this->Order->set(array("Customer" => array("id" => $customer_id)));
}
$this->Order->set(array('LineItem' => $items));
$this->Order->saveAssociated();

最后一点,您似乎正在实现一个购物车。如果是这种情况,也许使用单独ShoppingCart的而不是Orderfinalized标志的会更清楚。

于 2012-10-01T08:52:27.267 回答
2

您是否尝试过以下操作:

$this->Order->saveAll(array(
    'Order' => array(
        'id' => 5,
        'person_id' => $this->Session->read('Person.id'),
        'amount' => $total,
        'currency_id' => $code                   
    ),
'Lineitem' => $lineitems  /* a correctly-formatted array */
));

它与您所做的几乎相同:

$this->Order->id = 5;

也许这会解决你的问题。Cake 正在检查您是否设置了 id 字段,如果它在那里更新记录,如果没有找到它会创建新记录。

更新:然后可能在 saveAll 之前检查是否有 id 字段,然后将检查结果保存到某个布尔值并创建数组以保存由该布尔值确定,例如:

if($id_exist) $order['Order']['id'] = 5;
$order['Order']['id'] = 5;
$order['Order']['person_id'] = $this->Session->read('Person.id'),
$order['Order']['amount'] = $total;
$order['Order']['currency_id'] = $code;

    $this->Order->saveAll(array(
    'Order' => $order,
'Lineitem' => $lineitems  /* a correctly-formatted array */
));
于 2012-10-01T08:59:43.967 回答