CakePHP

URLによってModel::displayFieldを動的に変更する

routes.phpで設定した特定のルーティングに従ったURLでアクセスされた場合にモデルのdisplayFieldを動的に変更する方法。例えばURLが「/hoge/users/」だったらdisplayField"hoge_name"、「/fuga/users/」だったら"fuga_name"にするなど。
誰が得するのかわからないですが、とりあえずメモっておく。

CakePHP1.2.7で確認。そろそろ1.3に移行したいところ。

要するに同じモデルでもアクセスされたURLによってdisplayFieldを切り替えたい場合、特に特定のモデルだけでなく全部一括で変えたい場合に使えるテクです。っていつ使うんだって思いますが、いつかそういうこともあります。

まずroutes.phpに次のように書いてあるとします。

Router::connect('/hoge/:controller/:action/*', array('hoge' => true)); // パターン1
Router::connect('/fuga/:controller/:action/*', array('fuga' => true)); // パターン2

こうすると「/hoge/任意のコントローラ/任意のアクション」も「/fuga/任意のコントローラ/任意のアクション」のいずれも動作的には同じになります。
ただし、コントローラ内で$this->paramsの内容に違いが出ます。パターン1では$this->params["hoge"]trueが入り、パターン2では$this->params["fuga"]trueが入った状態になります。コントローラ内ではこれを利用して動作を変化させることができます。

しかしモデル内では$this->paramsなどというプロパティが存在しません。最初に思いつくのはコントローラのbeforeFilterメソッド内で定数やらを定義してモデルのコンストラクタで読み取ったり図ろうとするでしょう。残念なことにモデルのコンストラクタの方が先に呼び出されるので、その方法は使えません。

そこで出てくるのが、Router::getParam()です。第1引数に”hoge”や”fuga”を与えてやれば、コントローラの$this->paramsを参照したときと同じものが得られます。ということでこれを利用して、app_model.phpのコンストラクタにガシっと処理を書いてしまいます。

class AppModel extends Model {
    public function __construct($id = false, $table = null, $ds = null) {
        if (Router::getParam('hoge')) {
            $this->displayField = 'hoge_name';
        } elseif (Router::getParam('fuga')) {
            $this->displayField = 'fuga_name';
        }
        parent::__construct($id, $table, $ds);
    }
}

これでモデル全部に対し、一括でdisplayFieldの変更ができます。
一部のモデルを除きたい場合は独自のプロパティやdisplayFieldのデフォルト値を設定するなどして、判定を追加すれば良いでしょう。

以上、誰得テクニックでした。

スポンサーリンク
管理人

システムえんじにゃー🐈
趣味はエレキギターなど。作曲したい。
WoWs/プリコネ
記事に関する質問はお気軽にどうぞ。

surface0 (さーふぇす)をフォローする
surface0 (さーふぇす)をフォローする

コメント

タイトルとURLをコピーしました