初めに
RailsでCSV出力を実装したので解説します。
今回はUserの名前、メールアドレス、アカウント作成日を出力してみます。
大まかな説明
RailsはModel, View, controllerとありますが、実際にいじるのはviewとcontrollerです。
viewではcsvファイルの作成と、出力ボタンを設置します。
controllerはcsvとして出力するオブジェクトを投げてファイル名を設定します。
#CSVファイルの作成(View)
viewにcsvファイルを作成するためのファイルを作ります。
xxxx.csv.ruby
と拡張子で作成します。
require 'csv'
CSV.generate do |csv|
csv_column_names = %w(name email created_at)
csv << csv_column_names
@users.each do |user|
column_values = [
user.name,
user.email,
user.created_at
]
csv << column_values
end
end
csv << column_names で表の列に入る名前を定義します。
csv << column_values で表の行に入る値を定義します。
CSV出力ボタンの設置(View)
<%= link_to "CSV出力", users_path(format: :csv), class: "btn btn-primary" %>
CSV出力のボタンを設置します。
ここではusersコントローラーのindexアクションで実行するのでusers_path
としていますが、
rails routes
で自分の実行したいアクションのルーティングを調べてから書いてください。
また(format: :csv)
と最後につけるのを忘れないようにしてください。
#フォーマットごとに出力内容を指定(Controller)
class UsersController < ApplicationController
def index
@users = User.all
respond_to do |format|
format.html do
#html用の処理を書く
end
format.csv do
#csv用の処理を書く
send_data render_to_string, filename: "(ファイル名).csv", type: :csv
endw
end
end
end
フォーマット後のに処理をわけて書きます。
ファイル名を変更したい時は、上記のように
send_data render_to_string, filename: "(ファイル名).csv", type: :csv
と書きます。
#リファクタリング
このままでも動くのですがViewでの書き方は改良の余地があります。
require 'csv'
CSV.generate do |csv|
csv_column_names = %w(name email created_at)
csv << csv_column_names
@users.pluck(*csv_column_names).each do |user|
csv << user
end
end
このようにすることによって、csv_column_namesの内容が変わっても修正する箇所が少なくて済みます。
また処理がeachだけの時よりもはやいです。
#最後に
以上でCSV出力の実装の終わりです。
なにか間違っているところなどあればご指摘ください!