LoginSignup
4
4

More than 5 years have passed since last update.

Rails - CSVダウンロード(サービスオブジェクト)

Last updated at Posted at 2015-08-23

#経緯

#特徴

  • サービスとしてMVCから切り離すので、アプリ本体をシンプルに保てる。
  • (ビューテンプレートなしに)各種ビューヘルパーへのアクセスが可能。
  • どのコントローラでも使用可能。

#やり方

##CSVモジュールをrequire

/config/application.rb
require File.expand_path('../boot', __FILE__)

require 'csv'
require 'rails/all'
# ...

##サービスオブジェクト

/app/helpers/csv_helper.rb
module CsvHelper

  class SendUsersCSV

    def initialize(users, controller)
      @users      = users
      @controller = controller
      @view       = controller.view_context
      send_csv
    end

    def send_csv
      # http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-headers
      @controller.send_data render_csv,
        type:        "application/csv",
        filename:    "users-#{Date.today}.csv",
        disposition: "attachment"
    end

    def render_csv
      # Set options if needed (e.g. :col_sep, :headers, etc)
      # http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/CSV.html#DEFAULT_OPTIONS
      options = { headers: true }

      attributes = %w(id username sign_in_count created_at confirmed_at updated_at)

      @output = CSV.generate(options) do |csv|
        # Column names in a first row
        csv << attributes

        # Write each record as an array of strings
        @users.unscoped.each do |user|
          csv << attributes.map{ |attr| user.send(attr) }
        end
      end
      @output
    end
  end
end

##コントローラ

class UsersController < ApplicationController
  include CsvHelper

  def index
    @users =  User.all

    respond_to do |format|
      format.html
      format.csv { SendUsersCSV.new(@users, self) }
    end
  end
end

##users_path(format: "csv")へのリンク

/app/views/users/index.html.haml
= link_to "CSVダウンロード", users_path(format: "csv"), class: "btn btn-warning"

##テスト

#資料

4
4
0

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
4
4