【Table】関連データの取得

関連データの取得

containメソッド

containで関連データをeagar loadして取得する。

<?php
$articles->find('all')->contain(['Authors', 'Comments']);
?>

ネストされた関連データを取得するときはドット記法を用いる。

<?php
$articles->find()->contain([
    'Authors.Addresses',
    'Comments.Authors'
]);
?>

関連データを条件によってフィルターすることができる。条件を指定するには、第二引数としてクエリーオブジェクトを受け取る無名関数を渡す。

<?php
$articles->find()->contain('Comments', function (Query $q) {
    return $q
        ->select(['body', 'author_id'])
        ->where(['Comments.approved' => true]);
});
?>
matchingメソッド

matchingメソッドで、関連データの条件にマッチするレコードを取得する。

<?php
$articles->find()->matching('Tags', function ($q) {
    return $q->where(['Tags.name' => 'CakePHP']);
});
?>

このメソッドはINNER JOIN句を生成するので、レコードが重複する可能性がある。distinctメソッドでプライマリーキーなど(ここではid)で重複行をまとめる。

<?php
$articles->find()->distinct('id')->matching(...);
?>
innerJoinWithメソッド

matchingと同様に関連データの条件でレコードを絞り込むが、matchingと違い関連データを取得しない。

<?php
$articles->find()->innerJoinWith('Tags', function ($q) {
    return $q->where(['Tags.name' => 'CakePHP']);
});
?>
notMatchingメソッド

matchingメソッドの逆。関連データの条件にマッチしないレコードを取得する。

<?php
$articles->find()->notMatching('Tags', function ($q) {
    return $q->where(['Tags.name' => 'CakePHP']);
});
?>

このメソッドはLEFT JOIN句を生成するので、レコードが重複する可能性がある。distinctメソッドでプライマリーキーなど(ここではid)で重複行をまとめる。

<?php
$articles->find()->distinct('id')->notMatching(...);
?>
leftJoinWithメソッド

すべての関連データをロードしたくはないが、関連データに基いて結果を計算したいときはleftJoinWithを使う。以下は記事 (Article) の全データと一緒に、記事ごとのコメント (Comment) 数をロードするときの例。

<?php
$articlesTable->find()->select(['total_comments' => $query->func()->count('Comments.id')])
    ->leftJoinWith('Comments')
    ->group(['Articles.id'])
    ->enableAutoFields(true);
?>