user984976
user984976

Reputation: 1334

CakePHP saveField -- beforeSave has no effect? (2.4.3)

I am 99% sure this must be a User error (because otherwise I am sure thousands of users would have posted that they are experiencing this problem) but I cannot figure out what is causing it!

I have the following code in Model:

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);
}

When I execute the function setProductPackagingId(), beforeSave fires and debug($this->data) returns:

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

However the SQL generated by CakePHP is only:

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

So, my version field added in beforeSave was missed somehow in the generated SQL?

Also, debug($options) in afterSave returns:

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

However, if I modify setProductPackagingId to the following:

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);
}

debug($this->data); in beforeSave() produces the same output as before.

However, the SQL produced is:

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

(version is included, which is what I wanted)

And debug($options) in afterSave() produces:

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

)

The only differences I can see here is that in the case where 'saveField()' was used, afterSave $options['fieldlist'] contained the parameter 'product_packaging_id'. However, when called from save(), $options['fieldlist'] was blank.

Is there something really obvious and stupid I am doing here which is stopping beforeSave from working correctly with saveField? Or is this the desired outcome in CakePHP? If I need to use beforeSave with saveField, am I supposed to execute another db update directly from within beforeSave (this sounds like a dumb idea for db I/O reasons). Or, do I somehow need to manually edit the 'fieldList' parameter so the other fields I want edited will actually be edited?

Upvotes: 1

Views: 3333

Answers (1)

Dave
Dave

Reputation: 29141

CakePHP's saveField() is used to save a single field.

That being said, why would Cake generate a query and include a different field that has nothing to do with the only field you specifically told it to save?

The answer is, it doesn't - it builds the query to update the only field you told it to. If you passed 20 fields with your data, then called saveField(), it would still only generate the query to update the field you specified, and completely ignore the rest of the data, regardless of whether it's in the initial data or added during 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

Upvotes: 2

Related Questions