#はじめに
今回はransack
というgemを使って検索機能を作っていきます。ransackは少ないコードで複雑な検索機能を簡単に作れるgemでとても便利です。また、ransack
ではソート機能も簡単に作れるのでそれも含めて作成していきます。
#準備
##バージョン等
・Rails 5.2.2
・ruby 2.5.0
##アプリケーションの作成
検索機能を作る前にアプリケーションを作成します。(もし作成中のサービスに検索機能を追加する方はここは無視して大丈夫です!!)
$ rails new search_sample
$ cd search_sample
Gemfileにransack
を追加し、bundle install
します
gem 'ransack'
$ bundle install
今回はscaffold
を利用してUser作成に関するアプリケーションの雛形を作成します。カラムは以下のとおりです
User |
---|
name |
age |
sex |
address |
$ rails g scaffold user name age:integer sex:integer address
$ rails db:migrate
#検索機能の追加
これから検索機能を作成していきます。目標は下のような検索フォームの作成です。
ransack
では様々な方法によって検索することができます。例は下のとおりです。これらはほんの一部です。
*
にはカラム名が入ります。
検索方法 | 意味(英語) | 意味 |
---|---|---|
*_eq |
equal | 等しい |
*_not_eq |
not equal | 等しくない |
*_lt |
less than | より小さい |
*_lteq |
less than or equal | より小さい(等しいものも含む) |
*_gt |
grater than | より大きい |
*_gteq |
grater than or equal | より大きい(等しいものも含む) |
*_cont |
contains value | 部分一致(内容を含む) |
コントローラーの内容を変更していきます。users_controller.rb
のindex
アクションを次のように変更してください。
#省略
def index
@q = User.ransack(params[:q])
@users = @q.result(distinct: true)
end
#省略
シードデータを作成します。
seeds.rb
に以下を追加しましょう。
User.create(name: 'けんたろう',age: '24', sex: '1', address: '新宿')
User.create(name: 'けんじ',age: '25', sex: '1', address: '渋谷')
User.create(name: 'かな',age: '21', sex: '2', address: '原宿')
User.create(name: 'みき',age: '17', sex: '2', address: '新宿')
User.create(name: 'かんな',age: '22', sex: '2', address: '池袋')
User.create(name: 'あきお',age: '13', sex: '1', address: '上野')
下のコマンドを入力します。
$ rails db:seed
##検索方法
###キーワード検索
下の図のように入力したキーワードと名前の部分一致から検索できるようにします。
<%= search_form_for @q do |f| %>
<%= f.label :name, "Keyword" %>
<%= f.search_field :name_cont %>
<%= f.submit "検索" %>
<% end %>
<!-- 省略 -->
<%= search_form_for @q do |f| %>
〜<% end %>
で囲った部分が検索フォームの部分になります。
name_cont
はname
カラムの単語の一部分を含むものを検索するという意味になります。
###数値の大小による検索
下の図のように年齢を入力した数字の大小で検索できるようにします。今回は〇〇以上〇〇未満といった形で検索できるようにします。
<%= search_form_for @q do |f| %>
<%= f.label :name, "Keyword" %>
<%= f.search_field :name_cont %>
<!--ここから追加-->
<%= f.label :age %>
<%= f.number_field :age_gteq %>以上〜
<%= f.number_field :age_lt %>未満
<!--ここまで追加-->
<%= f.submit "検索" %>
<% end %>
<!-- 省略 -->
age_gteq
によって入力した数字以上のage
を、age_lt
によって入力した数字未満のage
を検索するという意味になります。
###選択による検索
下の図のように性別をラジオボタンで選択し検索できるようにします。
<%= search_form_for @q do |f| %>
<%= f.label :name, "Keyword" %>
<%= f.search_field :name_cont %>
<%= f.label :age %>
<%= f.number_field :age_gteq %>以上〜
<%= f.number_field :age_lt %>未満
<!--ここから追加-->
<%= f.label :sex %>
<%= f.radio_button :sex_eq, '', {:checked => true} %>指定なし
<%= f.radio_button :sex_eq, 1 %>男性
<%= f.radio_button :sex_eq, 2 %>女性
<!--ここまで追加-->
<%= f.submit "検索" %>
<% end %>
<!-- 省略 -->
sex_eq
によって選んだものと数字の1,2が一致しているかどうかを検索します。また、*_eq
は完全一致の検索であるので、キーワード検索などにも利用できます。
###複数カラムでのキーワード検索
さきほど作ったキーワード検索で、名前だけでなく住所からも検索できるようにします。
<%= search_form_for @q do |f| %>
<!--ここから変更-->
<%= f.label :name_or_address, "Keyword" %>
<%= f.search_field :name_or_address_cont %>
<!--ここまで変更-->
<%= f.label :age %>
<%= f.number_field :age_gteq %>以上〜
<%= f.number_field :age_lt %>未満
<%= f.label :sex %>
<%= f.radio_button :sex_eq, '', {:checked => true} %>指定なし
<%= f.radio_button :sex_eq, 1 %>男性
<%= f.radio_button :sex_eq, 2 %>女性
<%= f.submit "検索" %>
<% end %>
<!-- 省略 -->
#ソート機能の追加
ソートとは並び替えのことです。
表示している情報を昇順降順で並び替える機能もransack
には備わっています。
index.html.erb
の以下の部分を変更します。
<!--省略-->
<tr>
<th>Name</th>
<th>Age</th>
<th>Sex</th>
<th>Address</th>
<th colspan="3"></th>
</tr>
<!--省略-->
上のコードを以下のように変更してください。
<!--省略-->
<tr>
<th><%= sort_link(@q, :name, "Name") %></th>
<th><%= sort_link(@q, :age, "Age") %></th>
<th><%= sort_link(@q, :sex, "Sex") %></th>
<th><%= sort_link(@q, :address, "Address") %></th>
<th colspan="3"></th>
</tr>
<!--省略-->
#終わりに
ransack
によって検索機能とソート機能を作成しました。
もしこれより良い実装方法や記事内のミスなどありましたらご指摘していただけるとありがたいです。