THE SAUNA これが噂のパラダイス
THE SAUNA これが噂のパラダイス
2010.09.06

モデル内でほかのモデルを扱う

まっちー

モデルの中で、他のモデルのデータをDBから持って来ようとした場合。例えば、Userモデルの中でPostモデルのデータを持って来るような場合ですね。そんな時は、App::importを使うという手もありますが、仮にUserとPostがアソシエーションによって紐づいている場合は、そんなことをしなくても持って来ることができる。

class User extends AppModel {

    function getData() {

        $this->bindModel(array('belongsTo' => array('Post')));

        $data = $this->Post->find('all');

    }

}

例えば上記のような書き方をすると、Userモデルの中でpostsテーブルのデータをfindできる。

実は俺、このことを知らなくて、二つのモデルにまたがった複雑な処理をするような場合には、まず一つ目のモデルで必要な処理を行って、そのデータをいったんコントローラーに渡して、そのデータを使って今度は別のテーブルで必要な処理を行っていたんだけど、これを知ったおかげで、多少複雑な処理でも一つのモデルのメソッドの中で完結できるので、コントローラーがめっちゃすっきりしました。

特にあれだね。アソシエーション先のモデルをさらに別のモデルとアソシエーションさせる場合とか、これを知っておくとかなーり便利な気がしなくもないです。

例えば、UserにPostが紐づいていて、そのPostにさらにTagが紐づくような場合とかね。

//Userモデルの中身
$this->bindModel(array('belongsTo' => array('Post')));

$this->Post->bindModel(array(
    'hasAndBelongsTo' => array(
        'Tag' => array(
            'className' => 'Tag',
            'joinTable' => 'posts_tags',
            'foreignKey' => 'post_id',
            'assciationForeignKey' => 'tag_id',
            'unique' => true,
        ),
    ),
));

$params = array('recursive' => 2);

$data = $this->find('all', $params);

たとえばこんな↑感じに書くと、ユーザーの情報と同時に、紐づいている投稿(ポスト)データに紐づいているタグデータを取ってこれたりします。ただ、紐づいている先の紐づいているデータを取るには、recursiveを2にする必要があります。Tagにさらにアソシエーションを設定して、そのデータも一緒に取って来るなら、recursiveは3にする必要がある。

まあ、例文があれなので、そんな変なデータの取得のしかたをするような設計ってあるのかと言われてしまったら、「うーん、どうだろ」って感じですが、知っておけばきっと役に立ちます。

ってか、立った(ク○ラではない。下ネタでもない)