CakePHP 3 を使うなら「カスタム Finder メソッド」は知らなきゃ損!

はじめに

CakePHP 3 にはカスタム Finder メソッドの仕組みがあります。これにより、データ取得時によく使う WHERE や ORDER BY などの条件をパッケージ化することができ、再利用や変更が簡単になります。

今日はブログサイトを例に、その実装方法と使用例をご紹介します。使用した CakePHP のバージョンは 3.8.4 です。

目次
  1. 実装方法と使用例
  2. メリット

1. 実装方法と使用例

1-1. モデルにカスタム Finder メソッドを実装

例えばブログサイトで、投稿の表示条件が以下だったとします。
(投稿は articles テーブルに格納)

  • articles テーブルの deleted = 0
  • articles テーブルの status_id = 3
    (1: 下書き、2: 承認待ち、3: 公開 みたいなイメージ)

この条件をカスタム Finder メソッドとして実装するには、ArticlesTable.php に下記のように追加します。

/src/Model/Table/ArticlesTable.php
use Cake\ORM\Query; // ← なければ追記
use Cake\ORM\Table; // ← なければ追記

class ArticlesTable extends Table
{
    // ▼これを追加
    public function findPublished(Query $query, array $options = [])
    {
        return $query->where([
            'Articles.deleted' => 0,
            'Articles.status_id' => 3
        ]);
    }
}

関数名は find●●●(~) になります。●●●部分の頭文字は大文字です。

1-2. 一覧画面での実装例

一覧画面で記事を取得する場合は、下記のように使います。

/src/Controller/ArticlesController.php
public function index()
{
    $query = $this->Articles->find('published');
    $articles = $this->paginate($query);
    $this->set(compact('articles'));
}

1-3. 記事詳細での実装例

記事詳細では以下のように。

/src/Controller/ArticlesController.php
public function view($id)
{
    $article = $this->Articles->findById($id)
        ->find('published')
        ->first();
    $this->set(compact('article'));
}

1-4. キーワード検索

そして、検索語句に一致する記事を取得する場合には下記のように書けます。

/src/Controller/ArticlesController.php
public function search()
{
    $keyword = $this->request->getQuery('kw');
    $query = $this->Articles->find('published')
        ->where(['Articles.body LIKE' => "%{$keyword}%"]);
    $articles = $this->paginate($query);
    $this->set(compact('articles'));
}

2. メリット

このように、何度も使用する共通条件(WHERE や ORDER BY など)をカスタム Finder メソッドとして実装すると、以下のメリットがあります。

  • コードの記述量が減る
  • 条件が変わったときには、カスタム Finder メソッドだけを直せばOK
  • どんなものを取得するのか分かりやすい

うまく活用すればコードの保守性がよくなりますので、CakePHP 3 を使用する場合は導入できる箇所はないか検討してみてください。