【问题标题】:CakePHP saveField -- beforeSave has no effect? (2.4.3)CakePHP saveField -- beforeSave 没有效果? (2.4.3)
【发布时间】:2013-12-15 04:50:25
【问题描述】:

我 99% 确定这一定是用户错误(因为否则我确信成千上万的用户会发布他们遇到此问题的帖子)但我无法弄清楚是什么原因造成的!

我在模型中有以下代码:

public function setProductPackagingId($id, $product_packaging_id)
{
    $this->id = $id;
    return $this->saveField('product_packaging_id', $product_packaging_id);
}

public function beforeSave()
{       
    $this->data[$this->alias]['version'] = 2;
    debug($this->data);
    return true;
}

public function afterSave($created, $options)
{
    debug($options);
}

当我执行 setProductPackagingId() 函数时,beforeSave 触发并且 debug($this->data) 返回:

array(
'PurchaseOrderProduct' => array(
    'id' => (int) 1,
    'product_packaging_id' => (int) 54,
    'version' => (int) 1000
  )
)

但是 CakePHP 生成的 SQL 只有:

UPDATE `roving_tms`.`purchase_order_products` SET `product_packaging_id` = 54  WHERE `roving_tms`.`purchase_order_products`.`id` = 1

那么,我在 beforeSave 中添加的版本字段在生成的 SQL 中不知何故被遗漏了?

另外,afterSave 中的 debug($options) 返回:

array(
'validate' => false,
'fieldList' => array(
    (int) 0 => 'product_packaging_id'
),
'callbacks' => true,
'counterCache' => true
)

但是,如果我将 setProductPackagingId 修改为以下内容:

public function setProductPackagingId($id, $product_packaging_id)
{   
    $purchase_order_product = array(
            'PurchaseOrderProduct' => array(
                    'id' => $id,
                    'product_packaging_id' => $product_packaging_id
                    ));

    return $this->save($purchase_order_product);
}

调试($this->data);在 beforeSave() 中产生与之前相同的输出。

但是,生成的 SQL 是:

UPDATE `roving_tms`.`purchase_order_products` SET `id` = 1, `product_packaging_id` = 54, `version` = 1000  WHERE `roving_tms`.`purchase_order_products`.`id` = 1

(包含版本,这是我想要的)

并且 afterSave() 中的 debug($options) 产生:

array(
'validate' => true,
'fieldList' => array(),
'callbacks' => true,
'counterCache' => true

)

我在这里看到的唯一区别是,在使用“saveField()”的情况下,afterSave $options['fieldlist'] 包含参数“product_packaging_id”。 但是,当从 save() 调用时,$options['fieldlist'] 是空白的。

我在这里做的事情是否真的很明显和愚蠢,它会阻止 beforeSave 与 saveField 一起正常工作?或者这是 CakePHP 想要的结果? 如果我需要将 beforeSave 与 saveField 一起使用,我是否应该直接从 beforeSave 中执行另一个数据库更新(由于 db I/O 原因,这听起来像是一个愚蠢的想法)。或者,我是否需要手动编辑“fieldList”参数,以便实际编辑我想要编辑的其他字段?

【问题讨论】:

    标签: cakephp cakephp-2.4


    【解决方案1】:

    CakePHP 的saveField() 用于保存单个字段。

    话虽如此,为什么 Cake 会生成一个查询并包含一个与您明确告诉它保存的唯一字段无关的不同字段?

    答案是,它没有 - 它构建查询以更新您告诉它的唯一字段。如果您将 20 个字段与您的数据一起传递,然后调用 saveField(),它仍然只会生成查询以更新您指定的字段,而完全忽略其余数据,无论它是在初始数据中还是在 @ 期间添加987654324@.

    "Used to save a single field value."
    

    http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savefield-string-fieldname-string-fieldvalue-validate-false

    【讨论】:

    • 我知道它用于更新单个字段,但是没有明确说明您不能通过 beforeSave 操作其他字段。我(错误地)认为它只是对单个字段执行常规 save() 操作的简写。也许这个信息应该在 beforeSave() api 中提供,因为我希望如果 beforeSave 函数执行,它应该照常执行。
    • 不,它在那里,阅读方法的整个文档:回调设置为 false 以禁用回调。使用“之前”或“之后”将仅启用这些回调。
    • @burzum 你是什么意思?回调正在执行,只是您在回调中编写的代码具有不同的效果,具体取决于它是从 save() 还是 saveField() 调用的。
    • Cakephp 正在生成一条 SQL 以尝试更新其他字段。就我而言。即使您尝试更新一个,它也会返回一个错误,即在完全不同的字段上不为空。是时候转向一个好的框架了。
    • @RonaldoSantana - 就像任何框架一样,如果你不理解它,并且做错了事情,你会得到错误的结果。幸运的是,CakePHP 拥有大量免费的在线信息、教程、文档等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    相关资源
    最近更新 更多