This repository has been archived by the owner on Jul 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Resolves #1337 - adds the module CsvExport to handle exporting CSV files - also supports exporting multiple CSVs at once in a zip file
- Loading branch information
Sydney Young
committed
Jan 31, 2016
1 parent
5d56bfe
commit 95a5c5f
Showing
10 changed files
with
143 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
module CsvExport | ||
require 'csv' | ||
require 'zip' | ||
|
||
PROTECTED_COLS = %w(id encrypted_password reset_password_token | ||
reset_password_sent_at) | ||
|
||
# generates a csv from the given model table | ||
# expects table to be an array with the following format: | ||
# [objects, columns] | ||
# where columns is optional; defaults to all columns except id | ||
def generate_csv(table) | ||
objects = table.first | ||
columns = table.size == 1 ? objects.first.attributes.keys : table[1] | ||
|
||
PROTECTED_COLS.each { |col| columns.delete(col) } | ||
|
||
CSV.generate(headers: true) do |csv| | ||
csv << columns | ||
|
||
objects.each do |o| | ||
csv << columns.map do |attr| | ||
s = o.send(attr) | ||
s.is_a?(ActiveRecord::Base) ? s.name : s | ||
end | ||
end | ||
end | ||
end | ||
|
||
# generates a zip file containing multiple CSVs | ||
# expects tables to be an array of arrays with the following format: | ||
# [[objects, columns], ...] | ||
# where columns is optional; defaults to all columns except id | ||
def generate_zip(tables) | ||
# create the CSVs | ||
csvs = tables.map { |model| generate_csv(model) } | ||
|
||
Zip::OutputStream.write_buffer do |stream| | ||
csvs.each_with_index do |csv, i| | ||
model_name = tables[i].first.first.class.name | ||
stream.put_next_entry "#{model_name}_#{Time.zone.today}.csv" | ||
stream.write csv | ||
end | ||
end.string | ||
end | ||
|
||
# downloads a csv of the given model table | ||
# expects table to be an array with the following format: | ||
# [objects, columns] | ||
# where columns is optional; defaults to all columns except id | ||
def download_csv(table, filename) | ||
send_data(generate_csv(table), filename: "#{filename}.csv") | ||
end | ||
|
||
# downloads a zip file containing multiple CSVs | ||
# expects tables to be an array of arrays with the following format: | ||
# [[objects, columns], ...] | ||
# where columns is optional; defaults to all columns except id | ||
def download_zip(tables, filename) | ||
send_data(generate_zip(tables), type: 'application/zip', | ||
filename: "#{filename}.zip") | ||
end | ||
|
||
def download_equipment_data | ||
categories = [Category.all, %w(name max_per_user max_checkout_length | ||
max_renewal_times max_renewal_length | ||
renewal_days_before_due sort_order)] | ||
models = [EquipmentModel.all, %w(category name description late_fee | ||
replacement_fee max_per_user | ||
max_renewal_length)] | ||
items = [EquipmentItem.all, %w(equipment_model name serial)] | ||
download_zip([categories, models, items], | ||
"EquipmentData_#{Time.zone.today}") | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
require 'spec_helper' | ||
include CsvExport | ||
|
||
describe CsvExport do | ||
before(:all) { FactoryGirl.create(:app_config) } | ||
|
||
MODELS = [:user, :category, :equipment_model, :equipment_item] | ||
PROTECTED_COLS = %w(id encrypted_password reset_password_token | ||
reset_password_sent_at) | ||
|
||
shared_examples 'builds a csv' do |model| | ||
let(:csv) do | ||
generate_csv([FactoryGirl.build_list(model, 5)]).split("\n") | ||
end | ||
|
||
it 'has the appropriate length' do | ||
expect(csv.size).to eq(6) | ||
end | ||
|
||
it 'has the appropriate columns' do | ||
expect(csv.first.split(',')).to eq( | ||
FactoryGirl.build(model).attributes.keys - PROTECTED_COLS) | ||
end | ||
|
||
it "doesn't include protected columns" do | ||
PROTECTED_COLS.each do |col| | ||
expect(csv.first.split(',')).not_to include(col) | ||
end | ||
end | ||
|
||
it 'limits columns appropriately' do | ||
cols = FactoryGirl.build(model).attributes.keys.sample(4) | ||
cols.delete 'id' if cols.include? 'id' | ||
csv = generate_csv([FactoryGirl.build_list(model, 5), cols]).split("\n") | ||
expect(csv.first.split(',')).to eq(cols) | ||
end | ||
end | ||
|
||
MODELS.each { |m| it_behaves_like 'builds a csv', m } | ||
end |