Search code examples
cakephpmodelcallbackbehaviorbefore-save

Is it safe to do query with Model while in Behavior's BeforeSave callback?


I don't see this documented anywhere, so I ask you, my dear Cake-eaters.

Inside a CakePHP's Behavior::BeforeSave(&$Model) method, I read and write changes to $Model->data array. Before I am finished, I need to read some other records from the database. I am worried that, if I use $Model->find(), it will overwrite the current data within the model, which is about to be saved.

Viewing the source code, the Model::find() function clearly resets the Model::$id variable. This is the same variable I later use to check if a field is being updated.

Here's an example:

<?php
    class UniqueBehavior extends ModelBehavior {

        function beforeSave(&$Model){

            $value = $Model->data[$Model->alias]['unique_field'];
            $query = array('conditions' => array('unique_field' => $value));
            if ($Model->find('first', $query){
                // Does $Model::find() reset the internal $Model->data array?
                $Model->data[$Model->alias]['unique_field'] = "..."
                //... some other code here
            }

            //ALSO...
            if ($Model->exists()) // Returns true if a record with the currently set ID exists.
            $slug = $Model->field('slug');

            // this should fetch the slug of the currently updated Model::id from the database
            // if I do find()'s, can I trust that the record I'm getting is the right one?
        }
    }
?>

Solution

  • you can always store the current id in $tmp and assign this stored id back to the model after you are finished

    $tmp = $Model->id;
    // ...
    $Model->id = $tmp;
    

    This way you don't run into problems using the Model-id.

    If it is save or not depends on how you work in your model. I - for example - never rely on this id. I always assign the id to the model manually prior to any update or delete call etc. But this is not necessary, of course. You have to be more careful then, though.