2015/07/19

ransackで検索とソートを組み込み

ransackを使って、番組リストの検索とソートをさくっと組み込みます。

Gemfileにgem 'ransack'書いて、bundle install。準備完了。

app/controllers/programs.rbのindex部は

に書き換え。searchとresultがransackの処理。
# @programs = Program.page(params[:page]) を下の2行に書き換え。
@q = Program.search(params[:q])
@programs = @q.result.page(params[:page])
controllerはこれだけで終わり。

ソートはテーブルヘッダをsort_linkで書き換える。
      <th><%= sort_link(@q, :channel_name, model_class.human_attribute_name(:channel_id)) %></th>
な風に。

views/programs/index.html.erb内の検索フォーム:

      <%= search_form_for @q do |f| %>
      

<%# include_blank:  でブランク行含む。文字列にすることも出来る%>

 <%= f.collection_select :channel_name_cont, Channel.all, :name, :name, include_blank: model_c\
lass.human_attribute_name(:channel_id) %>

 <%#= f.collection_select :channel_id_cont, Channel.all, :id, :name, include_blank: true %>

      
<%# multiple: true で複数選択 %>
<%= f.collection_select :category_name_cont, Category.where(cate_type:0).order(:name), :name,\
 :name, include_blank: model_class.human_attribute_name(:category_id), multiple: true %>
<%# multiple: true で複数選択 %>
<%= f.collection_select :category2_name_cont, Category.where(cate_type:1).order(:name), :name\
, :name, include_blank: model_class.human_attribute_name(:category2_id), multiple: true %>
<%# _gtでそれ以上という検索になる %>
<%= f.search_field :duration_gt, size: 5, placeholder: model_class.human_attribute_name(:dura\
tion) %>
<%= f.search_field :start_at_date_equals, size: 10, placeholder: model_class.human_attribute_\
name(:start_at) %>
<%= f.search_field :end_at_date_equals, size: 10, placeholder: model_class.human_attribute_na\
me(:end_at) %>
<%= f.search_field :title_cont, placeholder: model_class.human_attribute_name(:title) %>
<%= f.submit %>
<% end %>
channelは、collection_selectを使ってプルダウンメニュー型に
categoryは、Categoryレコード内に2タイプのカテゴリを混ぜているので、allではなくwhereでフィルタしています。
duration_gtですが、_gtを付けると「以上」を表現できます。
start_at_date_equalsの_date_equalsは、入力した文字列をDateに変換させる拡張をしています。

_date_equals拡張:
models/programs.rbに以下を加える

  ransacker :start_at do
    Arel.sql('date(start_at)')
  end
  ransacker :end_at do
    Arel.sql('date(end_at)')
  end
config/initializers/ransack.rbファイルを作成して以下のとおりとする

Ransack.configure do |config|
  # search_fieldで_date_equalsの内部処理                                                              
  config.add_predicate 'date_equals',
  arel_predicate: 'eq',
  formatter: proc {|v|
    begin
      v.to_date
    rescue
    end
    },
  validator: proc {|v| v.present? },
  type: :string
end
詳しくはこちら、
https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers
に書いてあるとおりです。

turbolinks問題
えーと、実はよくわかってはいないのですが、Rails4では、turbolinksとやらがデフォルトでつくようになったそうで、これが色んな所でよくわからない挙動というか挙動しない現象がありました。

ransackのsort_linkでソートした後にsearch_form_forのsubmitが効かなくなる!
link_to で、programs_path へ飛ばした後のsearch_form_forのsubmitが効かなくなる!
いろいろ調べて、jquery-turbolinksを入れてみましたが結果変わらず。
link_toに "data: {no_turbolink: 1}"を付けてみたところ機能はしましたが、sort_linkにこのオプションを付ける方法が分からず断念。

結局、turbolinksを外すことで解決となりました。

0 件のコメント:

コメントを投稿