Attaching and detaching model behaviors on-the-fly

Published on and tagged with behavior  cakephp  feature  model

A feature recently added to CakePHP is the possibility to attach and detach model behaviors on-the-fly (see changeset 6415). Let’s have a look at this feature with a simple example.

First we create a behavior which outputs a text before a find operation is performed:

// app/models/behaviors/example.php
class ExampleBehavior extends ModelBehavior {
    private $text = 'this is an example text';
	
    function setUp(&$model, $config) {
        if (isset($config['text'])) {
            $this->text = $config['text'];
        }
    }
	
    function beforeFind(&$model, $query) {
        echo $this->text;

        return true;
    }
}

The usual way to use a behavior is to define it with the $actsAs variable in the model. For example, to use the ExampleBehavior with the Post model, we would define it in the following way:

// app/models/post.php
class Post extends AppModel {
    var $actsAs = array('Example' => array('text' => 'some text'));
}

Every time we execute a find method of the Post model, the string “some text” is echoed.

With the new methods Model::attach() and Model::detach() With having a BehaviorCollection (with the methods attach() and detach()) as a property of the model more flexible scenarios are possible (even though I can’t think of any real use cases at the moment). If we want our Post model to act as Example only temporarily, we could write the following code:

// app/models/post.php
class Post extends AppModel {
}

// action in our controller
function index() {
    $this->Post->Behaviors->attach('Example', array('text' => 'hello world'));
    $this->set('all_posts', $this->Post->find('all'));
    $this->Post->Behaviors->detach('Example');
    $this->set('first_post', $this->Post->findById(1));
}

When we perform the find(‘all’) statement, our Post model acts as Example, i.e. the specified text is echoed, whereas with the findById statement, it no longer acts as Example, and so there is no output.

Happy baking :)

Update (2008-08-14): The example now uses the methods of the BehaviorCollection object, which is a property of the model. Thanks to kabturek for the hint!

14 comments baked

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License