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!
[…] Cakebaker blog tells us that attaching and detaching behaviors on the fly is now built in CakePHP core (we obviously have […]
Thanks for the heads up – have updated our old blog entry on how to do this….
Nice, this could be useful. It is always a good feature to be able to remove/add behaviors, helpers, model relationships, etc on-the-fly.
@Tarique, Marc: Thanks for your comments!
I have tried this with the Translate behaviour and it didn’t work
class Page extends AppModel
{
var $displayField = ‘name’;
var $actsAs = array();
function setLanguage($lang=null)
{
if($lang==null)
$lang = Configure::read(‘Config.language’);
else
Configure::write(‘Config.language’,$lang);
if(DEFAULT_LANGUAGE!=$lang)
$this->actsAs = array(‘Translate’ => array(‘content’, ‘name’, ‘title’));
$this->__construct(false, null, null);
}
}
This is my model Page, when I set up to the default language it retrives information from the pages tables, but if I change the language it retrives using the Translate behaviour from i18n table.
What I should do I have tried this and didn’t work
class Page extends AppModel
{
var $displayField = ‘name’;
var $actsAs = array(‘Translate’ => array(‘content’, ‘name’, ‘title’));
function setLanguage($lang=null)
{
if($lang==null)
$lang = Configure::read(‘Config.language’);
else
Configure::write(‘Config.language’,$lang);
if(DEFAULT_LANGUAGE==$lang)
$this->detach(‘Translate’);
}
}
@Boris: Hm, do you use the CakePHP version from the development branch?
[…] CakePHP 1.2 ã‹ã‚‰è¿½åŠ ã•れãŸãƒ“ヘイビアãŒå‹•çš„ã«è¿½åŠ ã€å‰Šé™¤ã§ãるよã†ã«ãªã‚‹ã‚ˆã†ã§ã™ã€‚ Attaching and detaching model behaviors on-the-fly – cakebaker […]
I use the beta version 1.2.0.6311-beta
So I think it should work the attach and detach behaviours.
@Boris: No, this feature is not yet in a release. As I have mentioned in the article it has been added in changeset 6415. So to use this feature you either have to use the version from the development branch or to wait for the next release…
[…] CakePHP 1.2 ã‹ã‚‰è¿½åŠ ã•れãŸãƒ“ヘイビアãŒå‹•çš„ã«è¿½åŠ ã€å‰Šé™¤ã§ãるよã†ã«ãªã‚‹ã‚ˆã†ã§ã™ã€‚ Attaching and detaching model behaviors on-the-fly – cakebaker […]
just a little update. in the freshest cake one should use
$this->Model->Behaviors->attach()/detach();
Model::Behaviors is an instance of BehaviorsCollection
http://api.cakephp.org/class_behavior_collection.html
@kabturek: Thanks for the hint! It is now fixed in the article.
[…] public links >> model The Martiel-Goldbeter model Saved by utriel on Wed 03-12-2008 Comment on Attaching and detaching model behaviors on-the-fly by … Saved by krisleslie on Tue 02-12-2008 Feasibility of PLoS ONE’s Peer Review Model? Saved by […]
Refere to this link I have posted full example to set $actsAs variable manually and it’s working 100% :
http://cakephptutor.wordpress.com/2012/12/26/actsas-in-cakephp