cakephp2.0.5で、時間(分)別検索機能を作成したいのですが、作業に詰まってしまいました。

よろしければ、どなたかご教授をお願いします。
検索機能はすでに完成済みです。
データベースに登録した映画の「上映時間(分)」で作品を検索したいのですが、なかなか上手くいきません。
search.ctpに以下を記述。
//上映時間
echo $this->Form->input('time',array('type' => 'select','multiple' => 'checkbox',
'options' => array('60-119' => '60分〜119分ぐらい','120-139' => '120分〜139分ぐらい')));?>
例えば60分〜119分ぐらいにチェックをつけて検索すれば、その時間帯に合った作品が抽出されるという仕組みです。
しかし、この方法ではどの作品も抽出されません。
今は、仕方なくテキストボックスに「100分」などと記述し、完全一致で検索しています。
どなたか、時間(分)別検索機能の設置の仕方を教えてください。
よろしくお願いします!

回答の条件
  • 1人10回まで
  • 13歳以上
  • 登録:2012/03/12 16:25:18
  • 終了:2012/03/19 16:30:07

ベストアンサー

id:tdoi No.1

tdoi回答回数174ベストアンサー獲得回数752012/03/12 18:00:11

ポイント100pt

もちろん、「最小時間テキストボックスと最大時間テキストボックスを用意し、それらの範囲をBETWEENで指定する」のでも実現できると思います。

INTEGERで管理しているという前提で、セレクトボックスでやるとすれば、適当に考えたところで、以下のような方法は可能かと。

1.フォームから受け取る60-119をパースして最小値、最大値を取得する

echo $this->Form->input('time',array('type' => 'select','multiple' => 'checkbox', 
'options' => array('60-119' => '60分~119分ぐらい','120-139' => '120分~139分ぐらい')));

これなら、

$range = explode('-', $this->data['Movie']['time']);

みたいなので取れますよね?
欠点は、フォームのvalueの値に規則性に関して、ControllerとViewで整合性を持たせる必要があることですね。

2.フォームから受け取る値を変えて置く

echo $this->Form->input('time',array('type' => 'select','multiple' => 'checkbox', 'options' => array('0' => '60分~119分ぐらい','1' => '120分~139分ぐらい')));

とかで画面を作っておいて、

$rangeList = array(0 => array(60, 119), 1 => array(120, 139));
$range = $rangeList[$this->data['Movie']['time']];

とかでいいのかと。
欠点は、ControllerとViewに記述が分かれてしまうことですね。

3.2の変形です

$rangeList = array(0 => array(60, 119), 1 => array(120, 139));
$options = array();
foreach ($rangeList as $key => $range) {
  $options[$key] = "{$range[0]}~{$range[1]}くらい}";
}
$this->set('options', $options);

みたいにオプションのパラメタをController側でセットしておき、、

echo $this->Form->input('time',array('type' => 'select','multiple' => 'checkbox', 
'options' => $options));

として出力する。
フォームから受け取ったデータは$rangeListを見れば、最大値と最小値が決定されますね。
欠点は、Controller側で表示する内容を操作する必要があります。

4.3の亜種です。

$rangeList = array(0 => array(60, 119), 1 => array(120, 139));
$this->set('rangeList', $rangeList);

とControllerでは用意しておき、View側で、

$options = array();
foreach ($rangeList as $key => $range) {
  $options[$key] = "{$range[0]}~{$range[1]}くらい}";
}
echo $this->Form->input('time',array('type' => 'select','multiple' => 'checkbox', 'options' => $options));

という風にして出すことです。
3の問題点は回避できるものの、Viewが若干繁雑です。

5.JavaScriptで頑張る
セレクトボックスが変更されたイベントを拾って、hiddenの最小と最小のテキストボックスにでも値を書いておく。
Viewだけで完結でき、Controllerとも疎な関係を保ちやすいですが、やや面倒です。


何かの参考になれば。

他1件のコメントを見る
id:tdoi

ん~。書いたのが消えてしまった・・・。
もう一度書くのは面倒なので、質問者さんにはメールで内容が伝わっていると期待して、

$conditions = array('OR' => array(array('time BETWEEN ? AND ?' => array(90, 120)),
                                                       array('time BETWEEN ? AND ?' => array(120, 150))));

というような指定になるように構造を組み替えて下さい。

2012/03/13 02:08:51
id:kyouryukun

ありがとうございます!
参考にさせていただきます。

2012/03/14 01:26:49
  • id:tdoi
    DB内の上映時間はどうやってもってるのでしょうか?
    INTEGERで扱っているなら、BETWEENで指定すればよいのでは?
    どうしても文字列で扱う必要があるなら、ORでつなげば検索自体は出来るのじゃないかと。
  • id:kyouryukun
    DB内ではintで値を格納しています。
    考えたのですが、
    最小時間テキストボックスと最大時間テキストボックスを用意し、
    それらの範囲をBETWEENで指定すればいいのでしょうか?

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません