LoginSignup
3
2

More than 5 years have passed since last update.

[Rails5]CSV.generate+pluckでCSVを出力する

Last updated at Posted at 2019-01-16

はじめに

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出力するような形で進めていきます。

・実装

まずはコントローラーを以下のように実装しました。

posts_controller.rb
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内がごちゃごちゃしそうだったので、別メソッドに逃しました。

続いでビューにリンクを設置します。

index.html.erb
<%= link_to 'csvダウンロード', 'index.csv' %>

もちろん、bootstrapを適用して

index.html.erb
<%= link_to 'csvダウンロード', 'index.csv', class: 'btn btn-default' %>

みたいにボタン化しちゃうのもアリ。
むしろそっちのほうが良いのかも。
けど今回は通常リンクで。

動作確認

では早速画面を見てみましょう。

cap1.png

csvダウンロードのリンクが表示されたので、押下してみます。

cap2.png

指定していた名前でダウンロードされました!

cap3.png

中身も大丈夫そうです!

追記(2019/01/17)

コメントでscivola様より、
別の手法を教わったので早速試してみました。

コントローラーではなくビューで生成処理をする

前述では、コントローラー内に
CSVの出力処理を組みましたが、それをビューで実施するという方法。
まずは"app/views/posts/"以下に"index.csv.ruby"ファイルを作成。

$ touch index.csv.ruby

そしてコントローラーで組んでいたロジックを移動。

index.csv.ruby
require 'csv'

CSV.generate do |csv|
  csv << Post.column_names
  Post.pluck(*Post.column_names).each{|data|csv << data}
end

そしてコントローラーのindex内を以下のように調整。

posts_controller.rb
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

動作確認

cap4.png

同じように動きました!

所感

とりあえず全件出力ですが、無事に実装することが出来ました。
最低限のものであれば、数行書くだけで出来るのは楽で良いですね。

追記(2019/01/17)

ビュー側で行う方法についてご教示頂いたあと、
CSV出力について調べている感じ、この方法をとってる方のほうが多そう?
"render_to_string"のリファレンス見るだけだとあまりピンとこなかったですが、
こういう風に使い方を実例としてやってみると分かりやすいですね。

おわりに

何かお気づきの点がありましたら、
ご指摘やアドバイス等頂けると大変助かります!

3
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2