[CakePHP3] アソシエーション先のデータをソート

ある単一エンティティをgetしたときに、hasManyでアソシエーションを張っているデータをソートして取得したい場合があります。

たとえば「著者」という親モデル(Authersモデルとする)からhasManyアソシエーションしてある「著書」モデル(Booksモデルとする)があるとしますよね。で、とある著者エンティティを著書つきで呼んできて、その著書たちを発行年月日カラム(published_dateとする)で並べ替えたいんじゃい!!という場合。

親エンティティ側でorder指定しようとしてもうまくいかず(考えてみれば親エンティティは単一だから当たり前)、どないすんねーーん!ってなって、できたのでメモ。


スポンサーリンク

1.モデル側で指定する場合

AutherエンティティをBooksつきで呼んでくるときは基本的に発行年月日順で呼んできたいねん。という場合は、モデル(テーブル)のアソシエーション定義のときにsortプロパティを指定してやればOKです。

//AuthersTable.phpのinitializeメソッド

$this->hasMany('Books', [
    'foreignKey' => 'publisher_id',
    'sort' => ['Books.published_date' => 'asc'] //これ
]);

ポイントは親エンティティ側のアソシエーション定義で指定するところです。sortプロパティを持てるのはhasManyアソシエーションだけで、belongsToアソシエーションからの指定はできません。

2.呼び出すときに指定する場合

基本的にはコントローラからになると思いますが、呼び出すときに指定することもできます。getであれfindであれpaginateであれ、containを用いる際に、hasManyと同じくsortプロパティが使えます。

//AuthersController.php

$this->paginate = [
    'contain' => [
        'Books' => [
            'sort' => ['Books.published_date' => 'asc'] //これ
        ]
    ]
];

このとき、モデル側で既にsortプロパティを設定していたとしても、呼び出し元の指定が上書きされます。なので、普段は発行年月日順で呼びたいけど、今回は著書名順に呼びたいねん!という要件にも対応可能です。


スポンサーリンク

3.参考URL

アソシエーション – hasManyアソシエーション | CakePHP 3.3 Red Velvet Cookbook

データの取り出しと結果セット – 関連を含んだソート | CakePHP 3.3 Red Velvet Cookbook

このところ基本的に索引先がCookbookです。いやあるべき姿なんだとは思いますが、CakePHP3って思ってたより日本語の情報少ないんですね…ということを痛感している今日この頃…。

この投稿の投稿者は おさみ です。ブックマーク用 パーマリンク

スポンサーリンク