CakePHPのSearchPluginでbetweenを使ってみたかった。
SearchPluginとの組み合わせでBetweenを使用する場合のコードを書いてみた。
機能を最小限に絞って、idを範囲指定、textをlikeで検索する。
model側のコード
idの内容はarray(id=>"開始|終了"); みたいになってる。
var $actsAs = array('Search.Searchable'); var $filterArgs = array( array('name' => 'id', 'type' => 'expression', 'method' => 'idBetween', 'field' => 'Sample.id BETWEEN ? AND ?'), array('name' => 'text', 'type' => 'like'), ); public function idBetween($data){ $input = $data['id']; $inputs = explode('|', $input); if($input) { $coditions = $inputs; } return $coditions; }
コントローラ側のコード
idはArrayで渡ってくるのでtypeはcheckboxで受ける。
var $components = array('Search.Prg'); var $presetVars = array( array('field' => 'id', 'type' => 'checkbox'), array('field' => 'text', 'type' => 'value'), ); function index() { $this->Prg->commonProcess(); $this->paginate['conditions'] = $this->Sample->parseCriteria($this->passedArgs); $this->set('samples', $this->paginate()); }
ビューのコード
view側のidの開始、終了はSample.id.0, Sample.id.1のフィールド名で配列になっている。
フィールド名にid.0だけ指定したらテーブルの情報が付かないのでSample.id.0という形式で指定。本当はid.start, id.endとしたいけどSearchPlugin側で加工した$this->dataの内容から連想配列のkeyが抜けるのであきらめた。
<h2><?php __('Search box');?></h2> <?php echo $this->Form->create('Sample', array('url' => array_merge(array('action' => 'index'), $this->params['pass']))); ?> <?php echo $this->Form->input('Sample.id.0', array('type' => 'text', 'label'=>'ID Start')); ?> <?php echo $this->Form->input('Sample.id.1', array('type' => 'text', 'label'=>'ID End')); ?> <?php echo $this->Form->input('text', array('type' => 'text')); ?> <?php echo $this->Form->submit(__('Search',true)); ?> <?php echo $this->Form->end(); ?>
サンプルの例は単純なケースなのでわざわざBetween使わなくてもidの部分を以下のように変更したほうがシンプルに実装出来る。
//model array('name' => 'start', 'type' => 'value', 'field' => 'Sample.id >'), array('name' => 'end', 'type' => 'value', 'field' => 'Sample.id <'), //controller array('field' => 'start', 'type' => 'value'), array('field' => 'end', 'type' => 'value'), // view <?php echo $this->Form->input('start', array('type' => 'text', 'label'=>'ID Start')); ?> <?php echo $this->Form->input('end', array('type' => 'text', 'label'=>'ID End')); ?>
わざわざBetweenを使用する場面ってなんだろうって思って調べてみたけど、実行速度的なメリットぐらいなのかな。
参考: http://sj6.org/mysql_datetime_index_faster/
betweenでID検索のデモ
http://nanagaiku.mydns.jp/php/searchdemo/