CakePHP

CakePHP recursive=2で不要な関係データの取り除き方

CakePHPの関係データ取得は、SQL文を自分で作らなくていいので重宝だ。で、「recursive=2」でテーブルの情報を検索した。検索 結果に必要な関係データがあるのは良いとして、不要なデータも当然付いてくるので、これを取り除いた検索結果を取得できないかな?というのを試してみた。

例としてテーブル、usergroups、users、posts、commentsとする。それぞれ

  • usergroups hasMany users
  • users hasMany posts/comments、users belongsTo usergroups
  • posts belongsTo users、posts hasMany comments
  • comments belongsTo posts/users

図で表すとこんな感じだろうか。

0303cakeassoc

ここで、一件のpostsデータを検索する際、ユーザの所属グループデータも一緒に求めたいとして「recursive=2」とした時、取得されるデータはどうなるだろうか?

$this->Post->recursive = 2;
$this->Post->findById($postid);

array(
[Post] => array(
    [id]
    [user_id]
    :
)
[User] => array(
    [id]
    [usergroup_id]
    :
    [Usergroup] => array(
        [id]
        :
    )
)
[Comment] => array(
    [0] => array(
        [id]
        [post_id]
        [user_id]
        :
        [Post] => array(
            [id]
            :
        )
        [User] => array(
            [id]
            :
        )
    :
    [1] => array(
    :
))

のようにデータが取得されると思う(試したのはこれらテーブルと異なるので、違ったらごめんなさい)。

目的とした「Usergroup」データの他に、「Comment」データに「Post」と「User」のデータも一緒に出力される。さて、本題で ある。ここで不要な「Post」と「User」データの取り除き方だ。実は、「unbindModel()」は長いので「recursive」で何とかな らないかと、「$this->Post->Comment->recursive = -1」とか、「$this->Post->Comment->belongsTo[‘User’][‘recursive’] = -1」とか試してみたのだが、うまく行かなかった。やっぱり、「unbindModel()」を使って解決することになった。

$this->Post->recursive = 2;
$this->Post->Comment->unbindModel(array(
    'belongsTo' => array('Post', 'User')));
$this->Post->findById($postid);

「Comment」データでユーザ名を取り込みたいときは、上の「belongsTo」で「User」を除けば良い。「recursive」は大変便利な機能だと改めて思った。