unbindModelでコンパクトなfindを心がける(脱recursive)
Railsに影響を受けているcakePHPは当然、強力なDBの操作に関する機能を提供してくれている。簡単に言うと、DBの各テーブルの関連を記述しておけば、1つデータを引くだけでその関連データも一緒に提供してくれる。
この機能はとっても便利なんですが、その分SQL文を発行するので、必要のない情報まで引いてくるとちょっと無駄。
modelのfind関数にはrecursiveという引数があって、そこに指定する値でどのレベルまで関連情報を引いてくるのかを設定できるみたいだけど、よく分からない。
ここに詳しい調査結果があるんだけど、やっぱり不便。
そんな時、mozillaのサイトのソースコードに便利なコードを見つけた。
<?php class AppModel extends Model { function unbindFully() { $unbind = array(); foreach ($this->belongsTo as $model=>$info) { $unbind['belongsTo'][] = $model; } foreach ($this->hasOne as $model=>$info) { $unbind['hasOne'][] = $model; } foreach ($this->hasMany as $model=>$info) { $unbind['hasMany'][] = $model; } foreach ($this->hasAndBelongsToMany as $model=>$info) { $unbind['hasAndBelongsToMany'][] = $model; } $this->unbindModel($unbind,false); } } ?>
最後のunbindModelの引数にfalseがあるけど、これがないと上手く動かなかったので個人的に追記してある。何か意味があるらしいけど忘れてしまった。とりあえずこの関数を実行すると一時的にテーブルの関連を全て解除してくれて単一テーブルだけにfindを実行できる。
このコードを、appフォルダ以下にapp_model.phpファイルを作って記述しておけばOKです。引数に利用したいmodel名を指定できるようにしたりすれば、もっと便利になるかも。
recursiveなんていう挙動の良く分からないものを利用するよりは、こうやって明示的に関連を操作するほうがいいんじゃないでしょうか?
お勧めのコードです。殆どの場面に置いては、そんな深い関連情報って必要ないんじゃないかなと思います。SQLクエリーが減るので極力利用するようにしています。