2013-12-15 1 views
1

Я на 99% уверен, что это ошибка пользователя (потому что в противном случае я уверен, что тысячи пользователей отправили бы сообщение, что они испытывают эту проблему), но я не могу понять, что вызывает это!CakePHP saveField - beforeSave не действует? (2.4.3)

У меня есть следующий код модели:

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 пожаров и отладки ($ this-> данные) возвращает:

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

Однако SQL-код, созданный CakePHP, только:

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

Итак, мое поле версии, добавленное в beforeSave, было пропущено так mehow в сгенерированном SQL?

Кроме того, отладка ($ опции) в afterSave возвращает:

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-> данные); in 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() производит:

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

)

Единственные отличия, которые я вижу здесь, это то, что в случае, когда 'saveField()' был used, afterSave $ options ['fieldlist'] содержит параметр 'product_packaging_id'. Однако, когда вызывается из save(), $ options ['fieldlist'] пусто.

Есть ли что-то действительно очевидное и глупое, я делаю здесь, что останавливается перед тем, как сохранить правильную работу с saveField? Или это желаемый результат в CakePHP? Если мне нужно использовать beforeSave с saveField, я должен выполнить другое обновление db непосредственно изнутри beforeSave (это звучит как глупая идея для причин ввода-вывода db). Или мне нужно каким-то образом вручную отредактировать параметр «fieldList», чтобы изменить другие поля, которые я хочу редактировать?

ответ

2

CakePHP's saveField() Используется для сохранения одного поля.

Как было сказано, почему Cake генерирует запрос и включает в себя другое поле, которое не имеет ничего общего с единственным полем, которое вы специально сказали ему сохранить?

Ответ: нет, он строит запрос для обновления единственного поля, которое вы ему сказали. Если вы передали 20 полей с вашими данными, а затем вызвали saveField(), он все равно будет генерировать запрос только для обновления указанного вами поля и полностью игнорировать остальные данные, независимо от того, находится ли он в исходных данных или добавлен во время beforeSave().

"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

+0

Я понимаю, что используется для обновления одного поля, однако это явно не указано, что вы не можете манипулировать другие поля через BeforeSave. Я был (ложно) под впечатлением, что это просто короткая рука для выполнения регулярной операции save() на одном поле. Возможно, эта информация должна быть предоставлена ​​в api beforeSave(), потому что я ожидал бы, что если функция beforeSave выполняется, она должна выполняться в обычном режиме. – user984976

+0

Нет, он есть, прочитайте всю документацию метода: callbacks Установите значение false, чтобы отключить обратные вызовы. Использование «до» или «после» будет включать только те обратные вызовы. – burzum

+0

@burzum, что вы имеете в виду? Обратный вызов выполняется только потому, что код, который вы пишете внутри обратного вызова, имеет другой эффект в зависимости от того, вызван ли он из save() или saveField(). – user984976