Ruby on Rails4でransackを使った検索機能の実装
2015.11.04
WEBサイト制作

今回は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/・データを格納するとこんな感じになります。
http://localhost:3000/products/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
Ransackで検索機能の実装を行う
Ransackに必要なGemをGemfileに追記する
Gemfile+gem "ransack"
bundle installする
$ bundle install
Ransackを使って検索できるようにコントローラに下記を追記する
app/controllers/products_controller.rbdef 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.erb01<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をご確認ください。
これで検索機能はできました。
Kaminariを追加しページングできるようにする
Kaminariで必要なGemをGemfileに追記する
Gemfile+gem 'kaminari'
bundle installする
$ bundle install
コントローラにRansackを使って検索できるように下記を追記する
app/controllers/products_controller.rbdef 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
これでページング機能はでき、一通り完成しました。
まとめ
gemをインストールするだけでレイアウトを整えて、検索機能、ページャーを実装するのにこんなに簡単にできるのかと思いました。他にも便利なgemはたくさんあるのでいつかご紹介できればなと思います。
参考サイト
・RailsにBootstrapデザインを適用する
・Ransackのススメ
・Railsでkaminariを使ってページネーションを実現する