Column
コラム

Ruby on Rails4でransackを使った検索機能の実装

  • Twitterでシェア
  • このエントリーをはてなブックマークに追加
  • Google+でシェア
  • follow us in feedly
Ruby on Rails4でransackを使った検索機能の実装

今回はBootstrapでレイアウトを整えてから、検索機能、ページャー機能の実装をしていきたいと思います。

Railsプロジェクトを作成する

・新規フォルダを作成する

$ mkdir products_search
$ cd products_search

・Gemfileを作成する

Gemfileを作成して、Railsをインストールするための記述を有効化します。
$ bundle init
$ vi Gemfile

- #gem "rails"
+ gem "rails"

・Bundlerを使ったGemパッケージのインストールする

以下のコマンドでRailsをインストール。
システムにインストールすると混乱のもとなので、`–path`オプションをつけてプロジェクトディレクトリ内にインストールするように指定しておきます。
$ bundle install --path vendor/bundle

・Railsプロジェクトを作成する。

※bundleでのGEMのインストール先をプロジェクト配下にGemをインストールしたい場合はGemのコマンド実行時に`bundle exec`をつける必要があります。
$ bundle exec rails new .
       exist  
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
    conflict  Gemfile
Overwrite /home/hgoto/rails/hello_rails/Gemfile? (enter "h" for help) [Ynaqdh] 
上記のようにGemfileがすでに存在するので上書きするか確認されます。
RailsのGemfileを利用したいので`Y`を押して上書きします。

・Gemfileのtherubyracerを有効化する。

あとでエラーになる可能性があるのでJavaScriptエンジンのtherubyracerをインストールします。
$ vi Gemfile

- #gem 'therubyracer', platforms: :ruby
+ gem 'therubyracer', platforms: :ruby

・bundle installする

Gemfileに更新があれば、未インストールのgemがインストールされます。
$ bundle install

・rails generateコマンドでファイルを生成する。

rails generateコマンドはコントローラ、モデル、テスト等のアプリケーションの土台などを自動生成してくれます。
scaffoldジェネレータでファイルを生成します。
$ bundel exec rails g scaffold Products name:string description:string price:integer stock:integer receipt_day:date
invoke active_record create db/migrate/20151030063026_create_products.rb create app/models/product.rb invoke test_unit create test/models/product_test.rb create test/fixtures/products.yml invoke resource_route route resources :products invoke scaffold_controller create app/controllers/products_controller.rb invoke erb create app/views/products create app/views/products/index.html.erb create app/views/products/edit.html.erb create app/views/products/show.html.erb create app/views/products/new.html.erb create app/views/products/_form.html.erb invoke test_unit create test/controllers/products_controller_test.rb invoke helper create app/helpers/products_helper.rb invoke test_unit invoke jbuilder create app/views/products/index.json.jbuilder create app/views/products/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/products.coffee invoke scss create app/assets/stylesheets/products.scss invoke scss create app/assets/stylesheets/scaffolds.scss

・DBを作成する

scaffoldで生成されたマイグレーションファイルを実行します。
$ bundle exec rake db:create
$ bundle exec rake db:migrate

・raisサーバーを起動する

$ bundle exec rails s

・下記URLにアクセスすると、作成したページが表示されます

http://localhost:3000/products/

ransack1


・データを格納するとこんな感じになります。

http://localhost:3000/products/

ransack3

Bootstrapを適用させる

先ほどscaffoldで生成したファイルにBootstrapを適用させてみたいと思います。

Bootstrapに必要なGemをインストールする為にGemfileを編集する

gem "therubyracer"
gem "less-rails"
gem "twitter-bootstrap-rails"

Gemfileを編集したらインストールを行う。

$ bundle install

Bootstrapをインストールする

$ bundle exec rails generate bootstrap:install less
less
      insert  app/assets/javascripts/application.js
      create  app/assets/javascripts/bootstrap.js.coffee
      create  app/assets/stylesheets/bootstrap_and_overrides.css.less
      create  config/locales/en.bootstrap.yml
        gsub  app/assets/stylesheets/application.css

LayoutファイルをBootstrap用に置換する

$ bundle exec rails g bootstrap:layout
置換してよいかの確認を効かれるので、Yを押して置換します。

テンプレートをBootstrap用に置換する

Productsコントローラのテンプレートにテーマを適用します。
$ bundle exec rails g bootstrap:themed Products
本当に置換してよいか聞かれるので、Yを押して置換してください。
これでテンプレートにBootstrapのテーマが適用されました。
http://localhost:3000/products

ransack4

Ransackで検索機能の実装を行う

Ransackに必要なGemをGemfileに追記する

Gemfile
+gem "ransack"

bundle installする

$ bundle install

Ransackを使って検索できるようにコントローラに下記を追記する

app/controllers/products_controller.rb
def index
-    @products = Product.all
+    @q = Product.ransack(params[:q])
+    @products = @q.result
end

検索用のフォームをビューに追加する

検索フォームを作成するためのsearch_form_forメソッドを使います。 入力フィールドのname値で、検索条件を指定することができます。 今回は完全一致「eq」、部分一致「cont」、複数条件での部分一致「or」「cont」、以上「gt」、以下「lt」等の検索の項目を 実装してみたいと思います。 下記のように記述して下さい。app/views/products/index.html.erb
01<div class="panel panel-default">
02  <div class="panel-heading">
03    <div class="panel-title">検索</div>
04  </div>
05  <div class="panel-body">
06    <%= search_form_for(@q, method: :get) do |f| %>
07      <div class="row">
08        <div class="col-sm-6">
09          <div class="form-group">
10            <%= f.label :name_eq %>
11            <%= f.text_field :name_eq, class: "form-control", placeholder: "完全一致" %>
12          </div>
13        </div>
14        <div class="col-sm-6">
15          <div class="form-group">
16            <%= f.label :description_cont %>
17            <%= f.text_field :description_cont, class: "form-control", placeholder: "部分一致" %>
18          <div>
19        </div>
20        <div class="col-sm-6">
21          <div class="form-group">
22            <%= f.label :name_or_description_cont %>
23            <%= f.text_field :name_or_description_cont, class: "form-control", placeholder: "複数条件部分一致" %>
24          </div>
25        </div>
26        <div class="col-sm-12">
27          <div class="form-inline">
28            <%= f.label :receipt_day %>
29            <%= f.date_select :receipt_day_gt, {include_blank: true, use_month_numbers: true, date_separator: ' / '}, class: "form-control" %>〜
30            <%= f.date_select :receipt_day_lt, {include_blank: true, use_month_numbers: true, date_separator: ' / '}, class: "form-control" %>
31          </div>
32        </div>
33      </div>
34      <%= f.submit '検索', class: "btn btn-primary" %>
35      <%= link_to 'クリア', url_for, class: "btn btn-default" %>
36    <% end %>
37  <div>
38</div>

11行目のカラム名「name」に「_eq」を記述した部分が完全一致検索。
17行目のカラム名「description」に「_cont」を記述した部分が部分一致検索。
23行目のカラム名「name」と「description」に「or」で繋ぎ最後に「_cont」を記述した部分が複数条件での部分一致。
29行目、30行目がカラム名に「_gt」「_lt」を使いある値より大きくてある値より小さいものにマッチさせています。
他にも検索条件には種類があるので詳しくはGitHubのransackをご確認ください。

これで検索機能はできました。

ransack5

Kaminariを追加しページングできるようにする

Kaminariで必要なGemをGemfileに追記する

Gemfile
+gem 'kaminari'

bundle installする

$ bundle install

コントローラにRansackを使って検索できるように下記を追記する

app/controllers/products_controller.rb
def index
    @q = Product.ransack(params[:q])
-    @products = @q.result
+    @products = @q.result.page(params[:page]).per(2)
end

ビューに検索用のフォームを追加する

app/views/products/index.html.erb
+<div class="row">
+  <div class="col-sm-12">
+    <%= paginate @products %>
+  </div>
+</div>

KaminariにBootstrapテーマを適用する

$ bundle exec rails g kaminari:views bootstrap3

これでページング機能はでき、一通り完成しました。

ransack6

まとめ

gemをインストールするだけでレイアウトを整えて、検索機能、ページャーを実装するのにこんなに簡単にできるのかと思いました。他にも便利なgemはたくさんあるのでいつかご紹介できればなと思います。

参考サイト

RailsにBootstrapデザインを適用する
Ransackのススメ
Railsでkaminariを使ってページネーションを実現する

この記事を共有する

この記事を読んだ方におすすめの記事

その他の最新コラム記事

人気記事ランキング

コラムカテゴリ
  • このエントリーをはてなブックマークに追加
  • follow us in feedly
お問い合わせ