QA@IT

RailsでATNDのような「絞り込む」機能を作る場合の質問

3688 PV

ATND( http://atnd.org/event/search/ )のイベント一覧を見ると、
「ジャンルで絞り込む」と「エリアで絞り込む」の機能があり、
例えば「東京都」の「グルメ」へと進むと、その条件にあったものが一覧に表示されます。

このような構造をRailsで作ろうと、Event、Area、Genreモデルをそれぞれ作り、
AreaとEvent、GenreとEventを親子関係にして、
ジャンルのみの絞り込みと、エリアのみの絞り込みはできたのですが、
そこからジャンルとエリアを合わせた絞り込みを作るのができません。

ATNDのURLを見ると、
http://atnd.org/event/search/kanto/tokyo/gourmet/?sp=1&selectTodofukenCd=13&selectAreaCd=3
のようになっているのですが、このジャンルとエリアを合わせた絞り込みはhas_manyとbelongs_toでは作れなく、
gemで作成するのでしょうか?作り方を教えて下さい。

よろしくお願いいたします。

回答

あまり綺麗ではありませんが、↓こんな感じで出来ないでしょうか?

Event.where( area_id: Area.where( "areas.name LIKE ?", "%#{params[:area]}%" ).pluck(:id) ).where( genre_id: Genre.where( "genres.name LIKE ?", "%#{params[:genre]}%" ).pluck(:id) )

eventsテーブルのarea_id、genre_idを、それぞれareaテーブルのLIKE文による検索結果のid配列、genresテーブルのLIKE文による検索結果のid配列で絞り込んでいます。


※追記(2013/03/18)

とりあえず値を渡すだけなら↓これでどうでしょう?
map内の配列の左側がユーザに表示される値、右側がデータとして渡されるvalueの値になればOKだと思います。

<%= f.select :area_id, Area.all.map{ |area| [area.name, area.id] }, { include_blank: "エリアを選択して下さい。" } %>
<%= f.select :genre_id, Genre.all.map{ |genre| [genre.name, genre.id] }, { include_blank: "ジャンルを選択して下さい。" %>

上記のフォームから値を受け取るのであれば、whereも下記だけで大丈夫な気がします。

Event.where( area_id: params[:area_id] ).where( genre_id: params[:genre_id] )
編集 履歴 (1)
  • 迅速なご回答ありがとうございます。pluckの存在を初めて知りました。
    恥ずかしながら教えて頂いた記述に合わせたformの書き方で手こずっています。自分なりに考えてareaだと<%= f.collection_select(:area_id, Area.find(:all), :id, :name, :prompt => "") %>のように書いて玉砕しましたがどう記述したらよろしいでしょう?
    -
  • 追記しましたー。(pluck便利ですよ) -
  • 参考にしたところ無事出来ました!
    と、同時にもっと勉強しなければと思いました(汗)
    この度は本当にありがとうございました!
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。