読者です 読者をやめる 読者になる 読者になる

Androidはワンツーパンチ 三歩進んで二歩下がる

Android卵プログラマーの記録ブログ

ransackでRailsアプリケーションに検索機能をつける

ruby on rails

Railsを勉強中です。

ransackというgemを使用して、検索機能を実装する一連の処理をメモします。

github.com

下準備

サンプルのアプリケーションを新しく作ります。
railsのバージョンは5.0.1です。

$ rails new _5.0.0.1_ new exm-ransack
$ cd exm-ransack

以前書いたエントリーと同じモデルを作り、同じデータを投入します。
↓以前のエントリ
sakura-bird1.hatenablog.com

サンプルデータ(csvデータ)をdbフォルダに入れておきます。
postal_code_tokyo_with_header.csv - Google ドライブ

今回はscaffoldでアプリケーションのひな型を作ります。

$ rails g scaffold PostalCode local_goverment_code:integer postal_code_old:integer postal_code:integer prefecture_katakana:string ward_katakana:string town_katakana:string prefecture:string ward:string town:string

$ rails db:migrate

db/seeds.rb に次のように記述します。

require 'csv'

PostalCode.delete_all

csv_data = CSV.read('db/postal_code_tokyo_with_header.csv', headers: true)
csv_data.each do |data|
  PostalCode.create!(data.to_hash)
end

$ rails db:seed
を実行します。
$ rails s
を実行します。
http://localhost:3000/postal_codes
にアクセスするとうまくデータが投入できているのがわかります。

f:id:sakura_bird1:20170301155738p:plain

検索機能を実装する

Gemfileに以下を追加する

gem ‘ransack'

$ bundle install
を実行します。

controllerのindexを次のように書き換えます。
postal_codes_controller.rb

# GET /postal_codes
# GET /postal_codes.json
def index
  # 検索フォームの入力内容で検索する
  @q = PostalCode.search(params[:q])

  # 重複を排除
  @postal_codes = @q.result(distinct: true)
end

viewに検索フォームを付けます。
app/views/postal_codes/index.html.erb

<%= search_form_for @q do |f| %>
    <%= f.label :town_cont %>
    <%= f.search_field :town_cont %>

    <%= f.submit %>
<% end %>

search_form_forというヘルパーメソッドが用意されており、検索フォームを生成してくれます。
:town_cont というのはtownフィールドに含まれている(contain)ものを検索するという意味です。

http://localhost:3000/postal_codes
にアクセスすると検索フォームが上の方に出来ていることがわかります。

f:id:sakura_bird1:20170301160124p:plain



検索フォームを次のようにフィールド名を_or_でつなげて書いたとすると、このフィールドのどこかで検索文字を含むものを結果に表示します。
フィールド名1_or_フィールド名2_(中略)_cont

<%= search_form_for @q do |f| %>
    <%= f.label :prefecture_katakana_or_ward_katakana_or_town_katakana_or_prefecture_or_ward_or_town_cont %>
    <%= f.search_field :prefecture_katakana_or_ward_katakana_or_town_katakana_or_prefecture_or_ward_or_town_cont %>

    <%= f.submit %>
<% end %>

f:id:sakura_bird1:20170301161459p:plain

以上です。