AkActiveRecordを試す

昨日からAkelosを使い始めた。AkActiveRecordでスラスラいけるかと思ったらそうでもないらしい。
とりあえずいろいろと挙動を覚え書き。

多対1 has_many <-> belongs_to

+---------+     +-------+
|  users  |     | roles |
+---------+     +-------+
| id      |  +--| id    |
| name    |  |  | name  |
| fname   |  |  +-------+
| role_id |--+
+---------+

上記のような関係のテーブルの場合、UserモデルとRoleモデルをそれぞれ以下のようにする。

app/models/user.php
<?php
class User extends AkActiveRecord
{
  var $belongs_to = 'role';
}
?>

app/models/role.php

<?php
class Role extends AkActiveRecord
{
  var $has_many = 'users';
}
?>

所有側が「has_many」所有される側が「belongs_to」ね。has_manyはuserの複数形usersで。
こうすることでコントローラでは以下のように使用できる。

app/controllers/page_controller.php

<?php
class PageController extends ApplicationController
{
  function example_1()
  {
    Ak::import('user');
    $User = new User(1);
    $User->role->load();
    $User->role->name = 'ロール名の変更';
    $User->role->save();
    $User->name = '氏名の変更';
    $User->save();
    $this->renderText($user->toYaml());
  }
  function example_2()
  {
    Ak::import('user');
    $User = new User();
    $user = $User->find(1, array('include' => 'role'));
    $user->role->name = 'ロール名の変更';
    $user->role->save();
    $user->name = '氏名の変更';
    $user->save();
    $this->renderText($user->toYaml());
  }
  function example_3()
  {
    Ak::import('role');
    $Role = new Role();
    $role = $Role->find(1, array('include' => 'user'));
    $role->name = 'ロール名の変更';
    $role->users[0]->name = '氏名の変更';
    $role->save();
    $this->renderText($role->toYaml());
  }
}
?>
example_1 普通の感じ
  • 「$User = new User(1);」でid=1のレコードをとってくる。
  • 「$User->role->load();」で関連するレコードをとってくる。
  • 「$User->role->name = 'hoge';」でユーザのロール名を変更。
  • 「$User->name = 'fuga';」ユーザ名を変更。
  • 「$User->role->save();」でロール名の変更を保存。
  • 「$User->save();」でユーザ名の変更を保存。
example_2 JOINでとってくる
  • 「$user = $User->find(1, array('include' => 'role'));」でid=1のユーザをroleとJOINしてとってくる

この方がJOINでとってくるのでちょっとやさしい。

example_3 所有側からの挙動
  • 「$role->users[0]->name = '氏名の変更';」でとりあえずとってきたユーザのうち最上行のユーザ名を変更(普通はこんな使い方しないけど)
  • 「$role->save()」所有側から呼んだ場合はusers[0]への変更もまとめてやってくれる。

更新がちょっと直感的じゃないような気がしないでもない。
気分的には「$user->save()」でroleへの変更も一緒にやって欲しいところだけど、所有する側じゃなければうまくいかない。所有される側で変更を保存する場合は各モデルでsave()を呼ばないといけないっぽい。まぁ意識すれば何とかなるかこのくらいなら。バグの元にならないといいけど。

次回はhas_and_belongs_to_manyについてやってみる。