Posts hasMany Comments
の関係で、最新のCommentsを3件だけ紐付けて取得したい場合を考える。
1. contain
に書く方法
再利用を考えなければ以下のように、contain
でクエリを書けばよい。
1 2 3 4 5 6 7 8 9 10 |
$Posts->find() ->contain([ 'Comments' => function (\Cake\ORM\Query $query) { // 最新3件 return $query->orderDesc('Comments.posted_at')->limit(3); }, 'Comments.CommentUsers', // <- コメント投稿者 ]); |
2. カスタムファインダーを定義する方法
カスタムファインダーを定義することで、再利用しやすくなる。
CommentsTable に findLatest3
というカスタムファインダーを定義する
1 2 3 4 5 6 7 8 9 10 11 |
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を指定して呼び出す。
1 2 3 4 5 6 |
$Posts->find() ->contain([ 'Comments' => ['finder' => 'latest3'], 'Comments.CommentUsers', // <- コメント投稿者 ]); |
3. カスタムファインダー+専用アソシエーションを定義する方法
Postsに最新のCommentsを3件取得するアソシエーションを別途定義すると、さらに再利用しやすくなる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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を呼び出す。
1 2 3 4 5 |
$Posts->find() ->contain([ 'LatestComments.CommentUsers', ]); |