Skip to content

Instantly share code, notes, and snippets.

@mnishiguchi
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save mnishiguchi/b23c7ff101ae7945166e to your computer and use it in GitHub Desktop.

Select an option

Save mnishiguchi/b23c7ff101ae7945166e to your computer and use it in GitHub Desktop.
Rails - .rubyテンプレートでCSVダウンロード ref: http://qiita.com/mnishiguchi/items/2e63dbe977cd278a4396
require File.expand_path('../boot', __FILE__)
require 'csv'
require 'rails/all'
# ...
module CsvHelper
def set_file_headers(options)
[:filename, :disposition].each do |arg|
raise ArgumentError, ":#{arg} option required" if options[arg].nil?
end
disposition = options[:disposition]
disposition += %(; filename="#{options[:filename]}") if options[:filename]
headers.merge!(
'Content-Disposition' => disposition,
'Content-Transfer-Encoding' => 'binary'
)
end
end
response.headers["Content-Disposition"] = 'attachment; filename="products.csv"'
CSV.generate do |csv|
csv << ["Name", "Price", "URL"]
@products.each do |product|
csv << [
product.name,
number_to_currency(product.price),
product_url(product)
]
end
end
response.headers["Content-Disposition"] = 'attachment; filename="products.csv"'
CSV.generate do |csv|
csv << ["Name", "Price", "URL"]
@products.each do |product|
csv << [
product.name,
number_to_currency(product.price),
product_url(product)
]
end
end
response.headers["Content-Disposition"] = 'attachment; filename="products.csv"'
CSV.generate do |csv|
csv << ["Name", "Price", "URL"]
@products.each do |product|
csv << [
product.name,
number_to_currency(product.price),
product_url(product)
]
end
end
"<pre class=\"debug_dump\"><kbd style=\"color:brown\">&quot;id,username,sign_in_count,created_at,confirmed_at,updated_at\\n1,Masa Nishiguchi,2,2015-07-30 20:30:25 UTC,2015-07-30 20:30:24 UTC,2015-08-02 22:07:55 UTC\\n2,Elton Gottlieb,0,2015-07-30 20:30:25 UTC,2015-07-30 20:30:25 UTC,2015-07-30 20:30:25 UTC\\n3, (...中略...) ,Elroy Howe,1,2015-07-30 20:30:25 UTC,2015-07-30 20:30:25 UTC,2015-07-31 13:40:07 UTC\\n&quot;</kbd></pre>"
# ==> 1. Set response headers
# http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-headers
set_file_headers filename: "users-#{Date.today}.csv",
disposition: "attachment"
# ==> 2. Set options if you want (e.g. :col_sep, :headers, etc)
# http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/CSV.html#DEFAULT_OPTIONS
options = { headers: true }
# ==> 3. Generate csv that is to be downloaded
attributes = %w(id username sign_in_count created_at confirmed_at updated_at)
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
= link_to "CSVダウンロード", users_path(format: "csv"), class: "btn btn-warning"
class UsersController < ApplicationController
include CsvHelper
# ...
def index
@users = User.all
end
# ...
end
RSpec.describe UsersController, type: :controller do
# ...
describe "admin user" do
before { log_in_as FactoryGirl.create(:admin), no_capybara: :true }
describe 'GET #index' do
before(:all) { 10.times { FactoryGirl.create(:user) } }
it "renders the index page" do
get :index
expect(response).to render_template :index
end
describe "CSV format" do
render_views #<== 強制的にrspecにビューを生成させる
before { get :index, format: "csv" }
let(:user) { User.first}
it { expect(response).to render_template :index }
it { expect(response.headers["Content-Type"]).to include "text/csv" }
attributes = %w(id username sign_in_count created_at confirmed_at updated_at)
attributes.each do |field|
it "has column name - #{field}" do
expect(response.body).to include field
end
end
attributes.each do |field|
it "has correct value for #{field}" do
expect(response.body).to include user[field].to_s
end
end
it "has correct number of rows" do
num_of_rows = 1 + User.all.count
expect(response.body.split(/\n/).size).to eq num_of_rows
end
end
end
# ...
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment