ハウテレビジョンブログ

『外資就活ドットコム』『Liiga』『Mond』を開発している株式会社ハウテレビジョンのブログです。

AROとなるモデルのparentNodeメソッドの書き方

日本語版cookbookの中の「ACLを用いた開発例」を紹介するページで、

リクエスタ(ARO)となるモデルの設定方法が書かれている。

 

ACL を制御するシンプルなアプリケーション

 

しかしこの例における parentNode メソッドの書き方は不適切なので、

英語版cookbook に従ったほうが良い。

 

parentNodeとは

parentNodeメソッドは AclBehavior のリクエスタとして使うモデルに必ず書く必要がある。

なぜなら、モデルのsave時にこれが呼び出され、

その返り値がarosテーブルのparent_idとして設定されるからである。

 

▼誤(日本語版cookbook)

[php]

var $name = 'User';

var $belongsTo = array('Group');

var $actsAs = array('Acl' => 'requester');

 

function parentNode() {

if (!$this->id && empty($this->data)) {

return null;

}

$data = $this->data;

if (empty($this->data)) {

$data = $this->read();

}

if (!$data['User']['group_id']) {

return null;

} else {

return array('Group' => array('id' => $data['User']['group_id']));

}

}

[/php]

このロジックだと、$this->data['User'] に group_idキーが無い場合にnullが返ってしまう。

すると users テーブルのgroup_idは(例えば)34なのにarosテーブルのparent_idはnull、という状態になってしまう。

ここは一致しなければならない。

 

group_id 以外のフィールドを更新したい時など、

$this->data に group_id が存在しない可能性はいくらでもある。

 

この問題は英語版cookbookでは修正されているので、そちらを参考にすれば良い。

 

▼正(英語版cookbook)

[php]

var $name = 'User';

var $belongsTo = array('Group');

var $actsAs = array('Acl' => array('type' => 'requester'));

 

function parentNode() {

if (!$this->id && empty($this->data)) {

return null;

}

if (isset($this->data['User']['group_id'])) {

$groupId = $this->data['User']['group_id'];

} else {

$groupId = $this->field('group_id');

}

if (!$groupId) {

return null;

} else {

return array('Group' => array('id' => $groupId));

}

}

[/php]