我在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的行,然后插入order_id为5的Lineitem
行。
但是,它只需在Order
中创建一个新行,然后使用新Order
记录中的新ID创建Listitem
行。
注意:我只是为了调试目的而设置上述ID,并轻松演示此问题。在我的最终代码中,我将检查当前person_id
是否已有待处理的订单,如果有,则执行$this->Order->id = $var;
,如果没有则$this->Order->create();
。
换句话说,有时我会希望它插入(在这种情况下我会发出$this->Order->create();
),有时我会希望它更新(在这种情况下我会发出$this->Order->id = $var;
)。上面的测试用例应该产生一个UPDATE,但它会生成一个INSERT。
知道我在这里做错了吗?
答案 0 :(得分:3)
传递给Model->saveAll()
的数组不包含订单的ID,因此Cake会创建一个新数组。如果要更新现有记录,可以在传递的数组中设置订单ID,也可以使用find检索它。 The documentation明确说明
如果要更新值,而不是创建新值,请确保 您正在将主键字段传递到数据数组
$order = $this->Order->findById(5);
// ... modify $order if needed
$this->Order->saveAll(array('Order' => $order, 'LineItem' => $items));
在您的情况下,您可能希望使用以下内容尽可能简洁。 Model::saveAssociated()
足够智能,可根据id
创建或更新,但您必须提供合适的输入。 Model::read($fields, $id)
初始化内部$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
而不是带有Order
标志的finalized
。
答案 1 :(得分: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字段,如果你在那里更新记录,如果没有找到则会创建新记录。
更新: 然后可能在你保存之前检查是否有id字段,然后将check的结果保存到某个布尔值并创建由此布尔值确定的数组,例如:
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 */
));