Posts hasMany Comments
の関係で、最新のCommentsを3件だけ紐付けて取得したい場合を考える。
1. contain
に書く方法
再利用を考えなければ以下のように、contain
でクエリを書けばよい。
$Posts->find()
->contain([
'Comments' => function (\Cake\ORM\Query $query) {
// 最新3件
return $query->orderDesc('Comments.posted_at')->limit(3);
},
'Comments.CommentUsers', // <- コメント投稿者
]);
2. カスタムファインダーを定義する方法
カスタムファインダーを定義することで、再利用しやすくなる。
CommentsTable に findLatest3
というカスタムファインダーを定義する
class CommentsTable extends Table {
// ... (snip)
public function findLatest3(\Cake\ORM\Query $query, array $options)
{
return $query->orderDesc($this->aliasField('posted_at'))->limit(3);
}
// ... (snip)
}
containでfinderを指定して呼び出す。
$Posts->find()
->contain([
'Comments' => ['finder' => 'latest3'],
'Comments.CommentUsers', // <- コメント投稿者
]);
3. カスタムファインダー+専用アソシエーションを定義する方法
Postsに最新のCommentsを3件取得するアソシエーションを別途定義すると、さらに再利用しやすくなる。
class PostsTable extends Table {
public function initialize(array $config)
{
// ... (snip)
$this->hasMany('Comments'); // 元のリレーション
$this->hasMany('LatestComments', [
'className' => 'Comments',
'foreignKey' => 'post_id',
'finder' => 'latest3',
'propertyName' => 'comments', // propertyNameを設定することで、Commentsリレーションと同プロパティ名で取得できるようにする
]);
// ... (snip)
}
}
containではLatestCommentsを呼び出す。
$Posts->find()
->contain([
'LatestComments.CommentUsers',
]);