2014年01月29日

Search Pluginで、orConditions() みたいなのを使いながら同時に絞り込む

ついでにもうひとつ書いておきます。

https://github.com/CakeDC/search
の Search Pluginの説明を見ると、 orConditions() のようなメソッドを自分で書くと、「同じキーワードで複数フィールドを検索できちゃったりするよ」と書いてあります。

モデル.php の中に、

public $filterArgs = array(
'filter' => array('type' => 'query', 'method' => 'orConditions'),
);

とか書いて、

public function orConditions($data = array()) {
$filter = $data['filter'];
$cond = array(
'OR' => array(
$this->alias . '.title LIKE' => '%' . $filter . '%',
$this->alias . '.body LIKE' => '%' . $filter . '%',
));
return $cond;
}

というコードに誘導してやれば、titleフィールドとbodyフィールドを両方検索できちゃいますよ、と。
でもこれをそのまま素直に使うと、検索項目が複数あるときに問題になってしまいます。

せっかくサンプルの標準状態では、
SQLのクエリが、
 ~~~ WHERE モデル.フィールドA='A' AND モデル.フィールドB='B' AND モデル.フィールドC='C'
のように絞り込みになっているのに、上記をそのままつっこむと、
 ~~~ WHERE モデル.フィールドA='A' OR モデル.title='B' OR モデル.body='B' AND モデル.フィールドC='C'
とかになってしまうんです。
これは使えない!

で、これの解決策ですが、ちょっと考えると思いつきます。
下記のように"きちんと"設定しましょう。

public function orConditions($data = array()) {
$filter = $data['filter'];
$cond = array(
'AND'=>array(
'OR' => array(
$this->alias . '.title LIKE' => '%' . $filter . '%',
$this->alias . '.body LIKE' => '%' . $filter . '%',
)
));
return $cond;
}


こうするだけで、

 ~~~ WHERE モデル.フィールドA='A' AND (モデル.title='B' OR モデル.body='B') AND モデル.フィールドC='C'

というSQLになります。






posted by SDozono at 17:17| 東京 ☀| Comment(0) | TrackBack(0) | CakePHP General | このブログの読者になる | 更新情報をチェックする

Search Plugin で、SQL Query: validateSearch エラー

ひさしぶりにCakePHPのプログラムを書いています。ほんとにひさしぶりだな〜。
CakePHP 1.X の時代から 2.X に突然ジャンプしたので、覚えることがけっこうあります。
あれ、core.php にはもう、あのSecurity.levelとかなくなってるぞ!!

こちらの記事、非常に興味深く読みました。

あかつきのお宿
Security.levelはどこへ消えた?(CakePHP2系の話)
http://norm-nois.com/blog/archives/2290

そうなのか!!
で、本題ですが、SecurityPlugin で下記のようなエラーが出ました。
(ちなみにPostgreSQLです。)
---------------------------------------
Database Error
Error: SQLSTATE[42601]: Syntax error: 7 ERROR: "validateSearch"またはその近辺で構文エラー LINE 1: validateSearch ^
SQL Query: validateSearch
Notice: If you want to customize this error message, create app\View\Errors\pdo_error.ctp
---------------------------------------
Cakeの規約に従っていないテーブルを使わなきゃいけないからかなーとか、色々考えてしまったのですが、結局この原因は、「SearchableBehavior.phpが正しく読み込めていないから」でした。

いろいろ見返して、結局、
public $actsAs=array("Search.Searchable");
とではなく、
public $actAs=array("Search.Searchable");
と書いてあるのに気がついて直しました。

そしたらきちんと動きました。(泣
恥ずかしながらドジりました(古いな―
posted by SDozono at 17:04| 東京 ☀| Comment(0) | TrackBack(0) | CakePHP General | このブログの読者になる | 更新情報をチェックする