はじめに
Railsの勉強として、今回はCSV出力をやってみました。
やり方はいろいろあるようですが、
今回は表題にあるようにCSV.generate+pluckで行ってみます。
検証環境
以下の環境で実施しました。
[client]
・MacOS Mojave(10.14.2)
・Vagrant 2.2.2
・VBoxManage 6.0.0
[virtual]
・CentOS 7.6
・Rails 5.2.2
・ruby 2.3.1
ご参考までに。
CSV出力処理の実装
・前提
事前にRails勉強用に作成したプロジェクトで進めます。
各MVCは適当に掲示板アプリを想定してPostsコントローラーなどを生成済みです。
(index,show,editの空ページが見れる程度)
$ rails g model post
$ rails g controller posts index show edit
・方針
その前提のもと、すでに作成していた
以下の既存処理に手を加えていきます。
方針としては一覧ページに出力リンクを設置して、
一覧情報をCSV出力するような形で進めていきます。
・実装
まずはコントローラーを以下のように実装しました。
require 'csv'
def index
respond_to do |format|
format.html do
# kaminari
# @posts = Post.page(params[:page])
# ransack
@search = Post.ransack(params[:q])
@posts = @search.result
end
format.csv do
send_data output_csv,
filename: "投稿情報.csv"
end
end
end
def output_csv
# 出力情報を整形する場合は別途調整!
CSV.generate do |csv|
csv << Post.column_names
Post.pluck(*Post.column_names).each{|data|csv << data}
end
end
(gemは以前に勉強していた副産物なので無視してください)
indexの中で、CSV出力処理もまとめて書いても良かったけど、
CSVの出力内容をカスタマイズすることになった場合、
index内がごちゃごちゃしそうだったので、別メソッドに逃しました。
続いでビューにリンクを設置します。
<%= link_to 'csvダウンロード', 'index.csv' %>
もちろん、bootstrapを適用して
<%= link_to 'csvダウンロード', 'index.csv', class: 'btn btn-default' %>
みたいにボタン化しちゃうのもアリ。
むしろそっちのほうが良いのかも。
けど今回は通常リンクで。
動作確認
では早速画面を見てみましょう。
csvダウンロードのリンクが表示されたので、押下してみます。
指定していた名前でダウンロードされました!
中身も大丈夫そうです!
追記(2019/01/17)
コメントでscivola様より、
別の手法を教わったので早速試してみました。
コントローラーではなくビューで生成処理をする
前述では、コントローラー内に
CSVの出力処理を組みましたが、それをビューで実施するという方法。
まずは"app/views/posts/"以下に"index.csv.ruby"ファイルを作成。
$ touch index.csv.ruby
そしてコントローラーで組んでいたロジックを移動。
require 'csv'
CSV.generate do |csv|
csv << Post.column_names
Post.pluck(*Post.column_names).each{|data|csv << data}
end
そしてコントローラーのindex内を以下のように調整。
def index
respond_to do |format|
format.html do
# kaminari
# @posts = Post.page(params[:page])
# ransack
@search = Post.ransack(params[:q])
@posts = @search.result
end
format.csv do
# メソッドを呼び出していた部分をrender_to_stringに変更
send_data render_to_string,
filename: "投稿情報.csv"
end
end
end
動作確認
同じように動きました!
所感
とりあえず全件出力ですが、無事に実装することが出来ました。
最低限のものであれば、数行書くだけで出来るのは楽で良いですね。
追記(2019/01/17)
ビュー側で行う方法についてご教示頂いたあと、
CSV出力について調べている感じ、この方法をとってる方のほうが多そう?
"render_to_string"のリファレンス見るだけだとあまりピンとこなかったですが、
こういう風に使い方を実例としてやってみると分かりやすいですね。
おわりに
何かお気づきの点がありましたら、
ご指摘やアドバイス等頂けると大変助かります!