CakePHPでSearchプラグインを使ってみた

CakePHPで検索機能を作るにはどうすればいいのかな?と思いGoogle検索してみると、Searchプラグインなるものを発見。
さっそく試してみた。
参考にしたサイト
Searchプラグインを使ってCakePHPに検索を実装する | mawatari.jp
その他、「CakePHP Search Plugin」でググってヒットするいろいろなサイトを参考にさせていただきました。

Searchプラグインの導入

まず、GitHubからCakeDC/Searchをダウンロードする。
https://github.com/CakeDC/search
ダウンロードしたsearch-master.zipを解凍し、search-masterフォルダをSearchにリネームしてapp/Pluginにコピーする。
app/core/bootstrap.phpに以下を追加する。

CakePlugin::load('Search');

これでSearchプラグインが使えるようになった。

Searchプラグインを使う

Searchプラグインの使用例は上記サイトをはじめいろいろなところで紹介されているのでそちらを見た方が分かりやすい。
ここでは検索条件にラジオボタンを使った場合について書いておくことにする。
例えばusersテーブルにgender(varchar(1))というフィールドがあって、m=男性、w=女性だとする。
検索条件として『○すべて ○男性 ○女性』みたいなラジオボタンのグループを作り、『男性/女性』が選択された場合はその条件で検索、『すべて』が選択された場合は検索条件に含めない、というようなことをやりたい。
検索画面のHTMLはこんな感じ

<input type="radio" name="data[User][gender]" id="UsergenderNone" class="rental" value="none" />すべて
<input type="radio" name="data[User][gender]" id="UsergenderW" class="rental" value="w" />女性
<input type="radio" name="data[User][gender]" id="UsergenderM" class="rental" value="m" />男性

モデル

<?php
class User extends AppModel{
    // ビヘイビアの定義
    public $actsAs = array('Search.Searchable');

    // 検索フィルタの定義
    public $filterArgs = array(
        // 独自のフィルタを定義
        'gender' => array('type' => 'query', 'method' => 'searchGender'),
    );

    // 検索用フィルタ
    function searchGender($data = array()){
        $filter = $data['gender'];
        // 「すべて」選択時は条件無し
        if (($filter=='m') || ($filter=='w')){
            $conditions = array('gender' => $filter);
        } else {
            $conditions = array();
        }
        return $conditions;
        }
    }
?>

まず、モデルでSearchビヘイビアを使用するためにactAsを定義する。
次に実際の検索条件を設定するためにfilterArgsを定義する。
検索パターンにはいろいろなものが用意されていて、例えば『'type' => 'value'』なら完全一致、『'type' => 'like'』なら部分一致という具合。
その中で『'type' => 'query'』とすると、『'method' => 'メソッド名'』で定義したメソッドを使用して独自の検索条件を定義できる。
今回の場合、「m:男性/w:女性」が選択された場合はその条件を定義して返し、それ以外の場合は空の配列を返すようにした。
実際には『array('m' => '男性', 'w' => '女性')』みたいなのをapp/Configに定義してbootstrap.phpで『Configure::load('xxx')』としておき、その配列に存在するか?みたいな判定方法がいいのかもしれない。
とりあえずこのqueryを使うとたいていの検索処理は実装できそう。