[Ruby on Rails 5] Exporting records to TSV in Rails 5.1
MIME type の追加など、手順を忘れていたので記事に起こしておきます。
[markdown]
“`prettyprinted
% rails –version
Rails 5.1.4
“`
こちらを参考にさせて頂きました。
> * [RailsでCSV/Excelのダウンロード機能の実装方法 – Rails Webook](http://ruby-rails.hatenadiary.com/entry/20141119/1416398472)
> * [#362 Exporting CSV and Excel – RailsCasts](http://railscasts.com/episodes/362-exporting-csv-and-excel)
> * [https://rubyplus.com/articles/4121-Exporting-Records-in-CSV-and-Excel-Formats-in-Rails-5](https://rubyplus.com/articles/4121-Exporting-Records-in-CSV-and-Excel-Formats-in-Rails-5)
## rails generate
省略。
`rails g` でこのようなプロジェクトを作成してあります。
“`db/schema.rb
ActiveRecord::Schema.define(version: 20180118080513) do
create_table “data”, force: :cascade, options: “ENGINE=InnoDB DEFAULT CHARSET=utf8” do |t|
t.integer “depth”
t.string “title”
t.string “filename”
t.text “description”
t.string “keywords”
t.text “content_1”
t.text “content_2”
t.datetime “created_at”, null: false
t.datetime “updated_at”, null: false
end
end
“`
## TSV Download
TSV は `CSV.generate(col_sep: “\t”)` で作成します。
> * [[Ruby] Rubyでヘッダ付きのCSVを生成する | deadwood](https://www.d-wood.com/blog/2015/11/14_7685.html)
### View
ダウンロードボタンをビューの一覧に追加します。
“`ruby:views/data/index.html.haml
.btn-group
= link_to ‘Download TSV’, data_path(format: ‘tsv’), class: ‘btn btn-primary’
“`
### Controller
[respond_to](http://railsdoc.com/references/respond_to) を利用して、フォーマットに応じた出力をコントローラで指定します。
“`ruby:controllers/data_controller.rb
class DataController < ApplicationController
# GET /data
# GET /data.json
# GET /data.tsv
def index
@data = Datum.all
respond_to do |format|
format.html
format.json { render json: @data }
format.tsv { send_data @data.to_csv(col_sep: "\t") }
end
end
end
``` ### Model モデルに `to_csv` メソッドを用意します。 ```ruby:models/datum.rb
class Datum < ApplicationRecord
def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |data|
csv << data.attributes.values_at(*column_names)
end
end
end
end
``` ### Config `require 'csv'` をします。 ```ruby:config/application.rb
require 'csv'
``` また未設定の場合、下記のようなエラーが表示されて、[Rails Guides](http://guides.rubyonrails.org/action_controller_overview.html#restful-downloads) を見て MIME type を登録してね、と言われます。 ```prettyprinted
To respond to a custom format, register it as a MIME type first: http://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. If you meant to respond to a variant like :tablet or :phone, not a custom format, be sure to nest your variant response within a format response: format.html { |html| html.tablet { ... } }
``` MIME type も追加しておきます。 > * [https://www.iana.org/assignments/media-types/text/tab-separated-values](https://www.iana.org/assignments/media-types/text/tab-separated-values)
> * [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml)
“`ruby:config/initializers/mime_types.rb
Mime::Type.register ‘text/tab-separated-values’, :tsv
“`
サーバを再起動するとダウンロードが可能になります。
## 補遺
View を用意するパターン。
> * [RailsでMVCを意識してシンプルにCSV出力 – Qiita](https://qiita.com/necojackarc/items/39e0f0c438363f7084db)
「Railsプロジェクトの作成」部分のメモ。
> * [RailsでCSV/Excelのダウンロード機能の実装方法 – Rails Webook](http://ruby-rails.hatenadiary.com/entry/20141119/1416398472)
“`ruby
# app/models/manufacture.rb
class Manufacture < ActiveRecord::Base
has_many :products
end
# app/contollers/products_contoller.rb
class ProductsController < ApplicationController
def index
# N+1問題のため、allではなくincludes
@products = Product.includes(:manufacture)
end
end
# app/models/product.rb
class Product < ActiveRecord::Base
belongs_to :manufacture
end
``` [/markdown]