(CakePHP 1.2.5)
ビヘイビアに定義されたメソッドは、モデル自身のメソッドであるかのように呼び出すことができます。
class FooBehavior extends ModelBehavior { function foo($model){ /* ... */ } } class Bar extends AppModel { var $actsAs = array('Foo'); } // in Controllers $this->Bar->foo();
しかしこの方法では Dynamic Finder のように動的に名前が変化するメソッドは実装できません。
ModelBehavior クラスの $mapMethods プロパティを使用すると、この制約を乗り越えることができます。$mapMethods は配列で、次のような構造をしています:
array( '/メソッド名に対する正規表現/' => '実際に呼び出されるメソッド' )
例えば '/^list/' => '_genericList' という設定を行った場合、listから始まる全てのメソッド呼び出しが、ビヘイビアの _genericList メソッドの呼び出しに変換されます。このとき _genericList メソッドの引数には元のメソッド名と引数が渡されます。ちょうど __call によるメソッドのオーバーロードと同じです。
この機能を活用して、あるカラムの値を配列として取得するための listColumn メソッドを作ってみます(Column はカラム名)。このメソッドは ListingBehavior に実装することにしましょう。
class ListingBehavior extends ModelBehavior { var $mapMethods = array('/^list[a-zA-z0-9]+$/' => '_listColumn'); function _listColumn($model, $methodName, $query=array()) { $column = substr($methodName, 4); $query = am($query, array('fields' => array($model->alias.".".$column))); $arr = $model->find('all', $query); if(is_array($arr)) { return Set::extract("/{$model->alias}/{$column}", $arr); } return $arr; } }
モデルにこのビヘイビアを組み込むと、任意のカラムに対して listXXX メソッドを呼び出すことができるようになります。
class User extends AppModel { var $actsAs = array('Listing'); } // in Controllers $this->User->listId(); $this->User->listUsername(array('conditions' => 'active = 1')); $this->User->listGroup_id();
メソッド名は小文字に変換されて渡されるので(これが仕様なのかバグなのか微妙なところです)、残念ながら Inflector::underscore を使うことはできません。