日本語版cookbookの中の「ACLを用いた開発例」を紹介するページで、
リクエスタ(ARO)となるモデルの設定方法が書かれている。
しかしこの例における 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]