暫くぶりに CakePHP でアプリケーションを作ろうかといろいろ構想練っている。その中でユーザーに提供したシステムを更新する際、、自動アップデート機能を盛り込みたいなぁ、と思って以前ブックマークしたsdozonoさんの記事「CakePHPのワンクリックアップデート用ソースコード」を見ていたら、「ClassRegistry」なるクラスがあった。
そこで早速検索して、忘れても直ぐに参照できるよういつものようにブログにメモ。
コントローラで複数のモデルを参照、利用する際、プロパティ $uses に参照するモデル名の配列を与える。
$uses = array('Post', 'User')
ところでコントローラのアクションは、プログラムの実行に先立って $uses に登録されたモデル全てを読み込むので、モデルのメソッドを利用しないアクションでは効率が悪くなる。そこで、利用するアクションのみモデルをロードする、ClassRegistry を利用する。
$Post = ClassRegistry::init('Post'); $posts = $Post->find('all'); 又は $posts = ClassRegistry::init('Post')->find('all')
既に読み込まれていれば、ビューで利用できる。
$Category = ClassRegistry::getObject('Category'); $categories = $Post->find('list');
App::import() でも処理できるが、データベースの接続先が $default に固定されてしまい、ユニットテストで利用できないので ClassRegistry の利用をするといいらしい。
参考ページ
cakephperさん:色々なモデルからデータを読み込んでViewにセットする
bennyleeさん:ClassRegistryの備忘録
foldrrさん:CakePHP モデルの読み込みは App::import ではなく ClassRegistry::init で
hiromi2424さん:ClassRegistry徹底解剖
(CakePHP Ver.1.3.9)
追記1
ページに表示するメインナビゲーションやサイドバーに表示するコンポーネントなど、ページの主文と関係ないデータを表示したいときどうしたらいいだろうか?
解決方法の1つとして、Elements から ClassRegistry を利用してモデルのメソッドを呼び出すといいだろう。
MVCの構成から、「View から Model を呼び出すべきでない」、という考えもあるのであまり深くは突っ込まない。
追記2
デバッグ時にデータベースのアクセスログを表示する方法、すっかり忘れていた。テンプレートに
<?php echo $this->element('sql_dump') ?>
を追加する。