[Ruby on Rails 5] Exporting Ransack results to CSV in Rails 5.1
Ransack の導入について、かんたんにまとめておきます。
[markdown]
“`prettyprinted
Rails 5.1.4
ransack 1.8.6
“`
こちらを参考にさせて頂きました。
> * [activerecord-hackery/ransack: Object-based searching.](https://github.com/activerecord-hackery/ransack)
> * [Railsでransackを使って検索機能を作成する – Rails Webook](http://ruby-rails.hatenadiary.com/entry/20141008/1412774436)
> * [#370 Ransack – RailsCasts](http://railscasts.com/episodes/370-ransack)
## rails generate
省略。下記の続きです。
正確には、この記事では TSV 出力を実装しています。
> * [[Ruby on Rails 5] Exporting records to TSV in Rails 5.1 | deadwood](https://www.d-wood.com/blog/2018/01/26_9443.html)
## Installation
`bundle install` します。
“`ruby:Gemfile
gem ‘ransack’
“`
## Search form
インデックスページにサーチフォームを追加します。
### Controller
“`ruby:app/controllers/data_controller.rb
class DataController < ApplicationController
# GET /data
# GET /data.tsv
def index
@q = Datum.ransack(params[:q])
@data = @q.result(distinct: true)
respond_to do |format|
format.html
format.tsv { send_data @data.to_csv(col_sep: "\t"), filename: "data-#{Time.zone.now.strftime('%d%m%Y%H%M')}.tsv" }
end
end
``` `result` > resutはActiveRecord::Relationを返すので、SQLは普通のActiveRecord同様遅延評価されますし、さらにwhereを繋げたり、kaminariでページングしたりすることもできます。また、to_sqlで発行されるSQLを確認することもできます。
>
> [Ransackのススメ – Qiita](https://qiita.com/nysalor/items/9a95d91f2b97a08b96b0)
`distinct: true`
> * [activerecord-hackery/ransack: Object-based searching.](https://github.com/activerecord-hackery/ransack#problem-with-distinct-selects)
### View
`search_form_for` ヘルパーを利用します。
Haml と [Bootstrap v4](https://getbootstrap.com/docs/4.0/components/forms/) でスタイリングすると、下記のようになります。
“`ruby:app/views/data/index.html.haml
= search_form_for(@q, class: ‘form-inline’) do |f|
.form-group
= f.label :title_or_filename_cont
= f.search_field :title_or_filename_cont, class: ‘form-control mx-sm-3 mb-2’
= f.submit ‘Submit’, class: ‘btn btn-primary mb-2’
“`
検索条件の指定には、`_or_` や `_cont` のような [Search Matchers](https://github.com/activerecord-hackery/ransack#search-matchers) を利用します。
## CSV download
ダウンロードボタンを追加します。
### View
Ransack の検索結果には、以下のようなパラメータが渡っていました。
“`ruby
{“utf8″=>”✓”, “q”=>{“title_or_filename_cont”=>”tex”}, “commit”=>”Submit”, “controller”=>”data”, “action”=>”index”}
“`
検索結果をダウンロードさせるには、`link_to` にパラメータが渡るように修正(`q: request.params[:q]`)します。
> * [Railsのlink_toにパラメータを追加する – Rails Webook](http://ruby-rails.hatenadiary.com/entry/20150114/1421161200)
“`ruby:app/views/data/index.html.haml
.btn-group
= link_to ‘Download TSV’, data_path(q: request.params[:q], format: ‘tsv’), class: ‘btn btn-primary’
“`
## Sort link
テーブルのタイトルクリックで、昇順や降順表示をさせます。
### View
`sort_link` ヘルパーを利用します。
このままで表示順も CSV download に反映されます。
“`ruby:app/views/data/index.html.haml
.table-responsive
%table.table.table-striped
%thead
%tr
%th= sort_link(@q, :depth)
%th= sort_link(@q, :title)
%th= sort_link(@q, :filename, ‘Filename’, default_order: :desc)
%th Description
%th Keywords
%th Content 1
%th Content 2
%th
%th
%th
%tbody
– @data.each do |datum|
“`
[/markdown]