csv_rb 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile +24 -0
  4. data/Gemfile.lock +250 -0
  5. data/Guardfile +16 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +510 -0
  8. data/Rakefile +29 -0
  9. data/lib/csv_rb/action_controller.rb +66 -0
  10. data/lib/csv_rb/plain_builder.rb +27 -0
  11. data/lib/csv_rb/railtie.rb +16 -0
  12. data/lib/csv_rb/stream_csv_deflator.rb +25 -0
  13. data/lib/csv_rb/template_handler.rb +31 -0
  14. data/lib/csv_rb/version.rb +5 -0
  15. data/lib/csv_rb.rb +6 -0
  16. data/lib/tasks/csv_rb_tasks.rake +4 -0
  17. data/spec/ci.rb +4 -0
  18. data/spec/csv_rb_builder_spec.rb +39 -0
  19. data/spec/csv_rb_mailer_spec.rb +17 -0
  20. data/spec/csv_rb_renderer_spec.rb +18 -0
  21. data/spec/csv_rb_request_spec.rb +220 -0
  22. data/spec/dummy/Rakefile +6 -0
  23. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  24. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  26. data/spec/dummy/app/controllers/home_controller.rb +58 -0
  27. data/spec/dummy/app/controllers/likes_controller.rb +20 -0
  28. data/spec/dummy/app/controllers/users_controller.rb +39 -0
  29. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  30. data/spec/dummy/app/mailers/notifier.rb +14 -0
  31. data/spec/dummy/app/models/like.rb +3 -0
  32. data/spec/dummy/app/models/user.rb +24 -0
  33. data/spec/dummy/app/views/home/_cover_sheet.csv.csvrb +1 -0
  34. data/spec/dummy/app/views/home/index.csv.csvrb +2 -0
  35. data/spec/dummy/app/views/home/index.html.erb +4 -0
  36. data/spec/dummy/app/views/home/only_html.html.erb +2 -0
  37. data/spec/dummy/app/views/home/useheader.csv.csvrb +1 -0
  38. data/spec/dummy/app/views/home/withpartial.csv.csvrb +2 -0
  39. data/spec/dummy/app/views/layouts/application.html.erb +12 -0
  40. data/spec/dummy/app/views/layouts/users.html.erb +12 -0
  41. data/spec/dummy/app/views/likes/index.csv.csvrb +4 -0
  42. data/spec/dummy/app/views/likes/index.html.erb +17 -0
  43. data/spec/dummy/app/views/notifier/instructions.html.erb +14 -0
  44. data/spec/dummy/app/views/notifier/instructions.txt.erb +6 -0
  45. data/spec/dummy/app/views/users/export.csv.csvrb +1 -0
  46. data/spec/dummy/app/views/users/index.csv.csvrb +1 -0
  47. data/spec/dummy/app/views/users/index.html.erb +23 -0
  48. data/spec/dummy/app/views/users/noaction.csv.csvrb +1 -0
  49. data/spec/dummy/app/views/users/respond_with.csv.csvrb +1 -0
  50. data/spec/dummy/app/views/users/send_instructions.csv.csvrb +2 -0
  51. data/spec/dummy/bin/bundle +3 -0
  52. data/spec/dummy/bin/rails +4 -0
  53. data/spec/dummy/bin/rake +4 -0
  54. data/spec/dummy/config/application.rb +22 -0
  55. data/spec/dummy/config/boot.rb +5 -0
  56. data/spec/dummy/config/database.yml +25 -0
  57. data/spec/dummy/config/environment.rb +5 -0
  58. data/spec/dummy/config/environments/development.rb +37 -0
  59. data/spec/dummy/config/environments/production.rb +83 -0
  60. data/spec/dummy/config/environments/test.rb +40 -0
  61. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  62. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  63. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  64. data/spec/dummy/config/initializers/inflections.rb +16 -0
  65. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  66. data/spec/dummy/config/initializers/secret_token.rb +2 -0
  67. data/spec/dummy/config/initializers/session_store.rb +3 -0
  68. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  69. data/spec/dummy/config/locales/en.yml +23 -0
  70. data/spec/dummy/config/routes.rb +17 -0
  71. data/spec/dummy/config/secrets.yml +22 -0
  72. data/spec/dummy/config.ru +4 -0
  73. data/spec/dummy/db/development.sqlite3 +0 -0
  74. data/spec/dummy/db/migrate/20120717192452_create_users.rb +12 -0
  75. data/spec/dummy/db/migrate/20121206210955_create_likes.rb +10 -0
  76. data/spec/dummy/db/schema.rb +31 -0
  77. data/spec/dummy/db/test.sqlite3 +0 -0
  78. data/spec/dummy/log/development.log +257 -0
  79. data/spec/dummy/log/test.log +25347 -0
  80. data/spec/dummy/public/404.html +67 -0
  81. data/spec/dummy/public/422.html +67 -0
  82. data/spec/dummy/public/500.html +66 -0
  83. data/spec/dummy/public/favicon.ico +0 -0
  84. data/spec/reset_gems.sh +2 -0
  85. data/spec/spec_helper.rb +39 -0
  86. data/spec/test_5.2.sh +16 -0
  87. data/spec/test_all_rails.sh +4 -0
  88. data/spec/test_revert.sh +3 -0
  89. metadata +413 -0
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+ require 'stringio'
5
+
6
+ module ActionView
7
+ class Template
8
+ module Handlers
9
+ class CSVRbBuilder
10
+
11
+ def default_format
12
+ Mime[:csv]
13
+ end
14
+
15
+ def call(template)
16
+ builder = StringIO.new
17
+ builder << "require 'csv';"
18
+ builder << "require 'csv_rb/plain_builder';"
19
+ builder << "csv ||= CSVRb::PlainBuilder.new;"
20
+ builder << template.source
21
+ builder << ";csv = csv.to_str if csv.is_a?(CSVRb::PlainBuilder); csv;"
22
+ builder.string
23
+ end
24
+
25
+ def handles_encoding?
26
+ true
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CSVRb
4
+ VERSION = '0.5.2'
5
+ end
data/lib/csv_rb.rb ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CSVRb
4
+ end
5
+
6
+ require 'csv_rb/railtie' if defined?(Rails)
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :csv_rb do
3
+ # # Task goes here
4
+ # end
data/spec/ci.rb ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ puts "Testing Rails 5"
4
+ exit system('cd spec/dummy && bundle install --without debug && bundle exec rake db:create && bundle exec rake db:migrate && cd ../../ && bundle exec rspec spec')
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'csvrb template handler' do
6
+
7
+ AB = ActionView::Template::Handlers::CSVRbBuilder
8
+ VT = Struct.new(:source, :locals)
9
+
10
+ let( :handler ) { AB.new }
11
+
12
+ let( :template ) do
13
+ src = <<-RUBY
14
+ csv << ['TEST', 'STUFF']
15
+ RUBY
16
+ VT.new(src, [])
17
+ end
18
+
19
+ context "Rails #{Rails.version}" do
20
+ # for testing if the author is set
21
+ # before do
22
+ # Rails.stub_chain(:application, :config, :csvrb_author).and_return( 'Elmer Fudd' )
23
+ # end
24
+
25
+ it "has csv format" do
26
+ expect(handler.default_format).to eq(mime_type)
27
+ end
28
+
29
+ it "compiles to an csv spreadsheet" do
30
+ csv = nil
31
+ eval( AB.new.call template )
32
+ expect{ csv = CSV.parse(csv) }.to_not raise_error
33
+ expect(csv[0][0]).to eq('TEST')
34
+ end
35
+
36
+ #TODO:
37
+ # Test if author field is set - does roo parse that?
38
+ end
39
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe "Mailer", type: :request do
6
+ before :each do
7
+ @user = User.create name: 'Elmer', last_name: 'Fudd', address: '1234 Somewhere, Over NY 11111', email: 'elmer@fudd.com'
8
+ end
9
+
10
+ it "attaches an csv file" do
11
+ visit "/users/#{@user.id}/send_instructions"
12
+ last_email = ActionMailer::Base.deliveries.last
13
+ expect(last_email.to).to eq([@user.email])
14
+ expect(last_email.attachments.first).to be
15
+ expect(last_email.attachments.first.content_type).to match(/#{mime_type}/)
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ require'spec_helper'
4
+
5
+ describe 'csvrb renderer' do
6
+
7
+ it "is registered" do
8
+ ActionController::Renderers::RENDERERS.include?(:csv)
9
+ end
10
+
11
+ it "has mime type" do
12
+ mime = mime_type
13
+ expect(mime).to be
14
+ expect(mime.to_sym).to eq(:csv)
15
+ expect(mime.to_s).to eq("text/csv")
16
+ end
17
+
18
+ end
@@ -0,0 +1,220 @@
1
+ # encoding: utf-8
2
+
3
+ class Encoder
4
+ def initialize(str)
5
+ @str = str
6
+ end
7
+
8
+ def to_utf8
9
+ return @str if is_utf8?
10
+ encoding = find_encoding
11
+ @str.force_encoding(encoding).encode('utf-8', invalid: :replace, undef: :replace)
12
+ end
13
+
14
+ def find_encoding
15
+ puts 'utf-8' if is_utf8?
16
+ return 'utf-8' if is_utf8?
17
+ puts 'iso-8859-1' if is_iso8859?
18
+ return 'iso-8859-1' if is_iso8859?
19
+ puts 'Windows-1252' if is_windows?
20
+ return 'Windows-1252' if is_windows?
21
+ raise ArgumentError.new "Invalid Encoding"
22
+ end
23
+
24
+ def is_utf8?
25
+ is_encoding?(Encoding::UTF_8)
26
+ end
27
+
28
+ def is_iso8859?
29
+ is_encoding?(Encoding::ISO_8859_1)
30
+ end
31
+
32
+ def is_windows?(str)
33
+ is_encoding?(Encoding::Windows_1252)
34
+ end
35
+
36
+ def is_encoding?(encoding_check)
37
+ case @str.encoding
38
+ when encoding_check
39
+ @str.valid_encoding?
40
+ when Encoding::ASCII_8BIT, Encoding::US_ASCII
41
+ @str.dup.force_encoding(encoding_check).valid_encoding?
42
+ else
43
+ false
44
+ end
45
+ end
46
+ end
47
+
48
+ require 'spec_helper'
49
+ describe 'csv_rb request', :type => :request do
50
+
51
+ after(:each) do
52
+ if File.exists? '/tmp/csvrb_temp.csv'
53
+ File.unlink '/tmp/csvrb_temp.csv'
54
+ end
55
+ end
56
+
57
+ it "has a working dummy app" do
58
+ @user1 = User.create name: 'Elmer', last_name: 'Fudd', address: '1234 Somewhere, Over NY 11111', email: 'elmer@fudd.com'
59
+ visit '/'
60
+ expect(page).to have_content("Hey, you")
61
+ end
62
+
63
+ it "downloads an csv file from default respond_to" do
64
+ visit '/home.csv'
65
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
66
+ File.open('/tmp/csvrb_temp.csv', 'w') {|f| f.write(page.source) }
67
+ csv = nil
68
+ expect{ csv = Roo::CSV.new('/tmp/csvrb_temp.csv') }.to_not raise_error
69
+ expect(csv.cell(1,1)).to eq('Bad')
70
+ end
71
+
72
+ it "downloads an csv file from respond_to while specifying filename" do
73
+ visit '/useheader.csv'
74
+
75
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
76
+ expect(page.response_headers['Content-Disposition']).to include("filename=\"filename_test.csv\"")
77
+ end
78
+
79
+ it "downloads an csv file from respond_to while specifying filename in direct format" do
80
+ visit '/useheader.csv?set_direct=true'
81
+
82
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
83
+ expect(page.response_headers['Content-Disposition']).to include("filename=\"filename_test.csv\"")
84
+
85
+ File.open('/tmp/csvrb_temp.csv', 'w') {|f| f.write(page.source) }
86
+ csv = nil
87
+ expect{ csv = Roo::CSV.new('/tmp/csvrb_temp.csv') }.to_not raise_error
88
+ expect(csv.cell(1,1)).to eq('Bad')
89
+ end
90
+
91
+ it "downloads an csv file from render statement with filename" do
92
+ visit '/another.csv'
93
+
94
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
95
+ expect(page.response_headers['Content-Disposition']).to include("filename=\"filename_test.csv\"")
96
+ end
97
+
98
+ it "downloads an csv file from as_csv model" do
99
+ User.destroy_all
100
+ @user1 = User.create name: 'Elmer', last_name: 'Fudd', address: '1234 Somewhere, Over NY 11111', email: 'elmer@fudd.com'
101
+ @user2 = User.create name: 'Bugs', last_name: 'Bunny', address: '1234 Left Turn, Albuquerque NM 22222', email: 'bugs@bunny.com'
102
+ visit '/users.csv'
103
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
104
+ File.open('/tmp/csvrb_temp.csv', 'w') {|f| f.write(page.source) }
105
+ csv = nil
106
+ expect{ csv = Roo::CSV.new('/tmp/csvrb_temp.csv') }.to_not raise_error
107
+ expect(csv.cell(1,1)).to eq('Elmer')
108
+ expect(csv.cell(2,1)).to eq('Bugs')
109
+ end
110
+
111
+ it "downloads an csv file with partial" do
112
+ visit '/withpartial.csv'
113
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
114
+ File.open('/tmp/csvrb_temp.csv', 'w') {|f| f.write(page.source) }
115
+ csv = nil
116
+ expect{ csv = Roo::CSV.new('/tmp/csvrb_temp.csv') }.to_not raise_error
117
+ expect(csv.cell(1,1,csv.sheets[0])).to eq('Cover')
118
+ expect(csv.cell(2,1,csv.sheets[1])).to eq("Bad")
119
+ end
120
+
121
+ it "handles nested resources" do
122
+ User.destroy_all
123
+ @user = User.create name: 'Bugs', last_name: 'Bunny', address: '1234 Left Turn, Albuquerque NM 22222', email: 'bugs@bunny.com'
124
+ @user.likes.create(:name => 'Carrots')
125
+ @user.likes.create(:name => 'Celery')
126
+ visit "/users/#{@user.id}/likes.csv"
127
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
128
+ File.open('/tmp/csvrb_temp.csv', 'w') {|f| f.write(page.source) }
129
+ csv = nil
130
+ expect{ csv = Roo::CSV.new('/tmp/csvrb_temp.csv') }.to_not raise_error
131
+ expect(csv.cell(1,1)).to eq('Bugs')
132
+ expect(csv.cell(2,1)).to eq('Carrots')
133
+ expect(csv.cell(3,1)).to eq('Celery')
134
+ end
135
+
136
+ it "handles reference to absolute paths" do
137
+ User.destroy_all
138
+ @user = User.create name: 'Bugs', last_name: 'Bunny', address: '1234 Left Turn, Albuquerque NM 22222', email: 'bugs@bunny.com'
139
+ visit "/users/#{@user.id}/render_elsewhere.csv"
140
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
141
+ [[1,false],[3,true],[4,true],[5,false]].reverse.each do |s|
142
+ visit "/home/render_elsewhere.csv?type=#{s[0]}"
143
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
144
+ end
145
+ end
146
+
147
+ it "uses respond_with" do
148
+ User.destroy_all
149
+ @user = User.create name: 'Responder', last_name: 'Bunny', address: '1234 Right Turn, Albuquerque NM 22222', email: 'bugs@bunny.com'
150
+ expect {
151
+ visit "/users/#{@user.id}.csv"
152
+ }.to_not raise_error
153
+ File.open('/tmp/csvrb_temp.csv', 'w') {|f| f.write(page.source) }
154
+ csv = nil
155
+ expect{ csv = Roo::CSV.new('/tmp/csvrb_temp.csv') }.to_not raise_error
156
+ expect(csv.cell(1,1)).to eq('Bad')
157
+ end
158
+
159
+ it "ignores layout" do
160
+ User.destroy_all
161
+ @user = User.create name: 'Responder', last_name: 'Bunny', address: '1234 Right Turn, Albuquerque NM 22222', email: 'bugs@bunny.com'
162
+ expect {
163
+ visit "/users/export/#{@user.id}.csv"
164
+ }.to_not raise_error
165
+
166
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
167
+ expect(page.response_headers['Content-Disposition']).to include("filename=\"export_#{@user.id}.csv\"")
168
+ end
169
+
170
+ it "handles missing format with render :csv" do
171
+ visit '/another'
172
+
173
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
174
+ expect(page.response_headers['Content-Disposition']).to include("filename=\"filename_test.csv\"")
175
+ # csv.cell(2,1).should == 'Bad'
176
+ end
177
+
178
+ Capybara.register_driver :mime_all do |app|
179
+ Capybara::RackTest::Driver.new(app, headers: { 'HTTP_ACCEPT' => '*/*' })
180
+ end
181
+
182
+ def puts_def_formats(title)
183
+ puts "default formats #{title.ljust(30)}: #{ActionView::Base.default_formats}"
184
+ end
185
+
186
+ it "mime all with render :csv and then :html" do
187
+ # puts_def_formats 'before'
188
+ ActionView::Base.default_formats.delete :csv # see notes
189
+ # puts_def_formats 'in my project'
190
+ Capybara.current_driver = :mime_all
191
+ visit '/another'
192
+ # puts_def_formats 'after render csv with */*'
193
+ expect{
194
+ visit '/home/only_html'
195
+ }.to_not raise_error
196
+ ActionView::Base.default_formats.push :csv # see notes
197
+
198
+ # Output:
199
+ # default formats before : [:html, :text, :js, :css, :ics, :csv, :vcf, :png, :jpeg, :gif, :bmp, :tiff, :mpeg, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :pdf, :zip, :csv]
200
+ # default formats in my project : [:html, :text, :js, :css, :ics, :csv, :vcf, :png, :jpeg, :gif, :bmp, :tiff, :mpeg, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :pdf, :zip]
201
+ # default formats after render csv with */* : [:csv, :text, :js, :css, :ics, :csv, :vcf, :png, :jpeg, :gif, :bmp, :tiff, :mpeg, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :pdf, :zip]
202
+
203
+ # Failure/Error: visit '/home/only_html'
204
+ # ActionView::MissingTemplate:
205
+ # Missing template home/only_html, application/only_html with {:locale=>[:en], :formats=>[:csv, :text, :js, :css, :ics, :csv, :vcf, :png, :jpeg, :gif, :bmp, :tiff, :mpeg, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :pdf, :zip], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :csvrb]}.
206
+ end
207
+
208
+ it "downloads an csv file when there is no action" do
209
+ User.destroy_all
210
+ @user1 = User.create name: 'Elmer', last_name: 'Fudd', address: '1234 Somewhere, Over NY 11111', email: 'elmer@fudd.com'
211
+ @user2 = User.create name: 'Bugs', last_name: 'Bunny', address: '1234 Left Turn, Albuquerque NM 22222', email: 'bugs@bunny.com'
212
+ visit '/users/noaction.csv'
213
+ expect(page.response_headers['Content-Type']).to eq(mime_type.to_s + "; charset=utf-8")
214
+ File.open('/tmp/csvrb_temp.csv', 'w') {|f| f.write(page.source) }
215
+ csv = nil
216
+ expect{ csv = Roo::CSV.new('/tmp/csvrb_temp.csv') }.to_not raise_error
217
+ expect(csv.cell(1,1)).to eq('Elmer')
218
+ expect(csv.cell(2,1)).to eq('Bugs')
219
+ end
220
+ end
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ class ApplicationController < ActionController::Base
4
+ # Prevent CSRF attacks by raising an exception.
5
+ # For APIs, you may want to use :null_session instead.
6
+ protect_from_forgery with: :exception
7
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+
3
+ #---
4
+ # Excerpted from "Crafting Rails Applications",
5
+ # published by The Pragmatic Bookshelf.
6
+ # Copyrights apply to this code. It may not be used to create training material,
7
+ # courses, books, articles, and the like. Contact us if you are in doubt.
8
+ # We make no guarantees that this code is fit for any purpose.
9
+ # Visit http://www.pragmaticprogrammer.com/titles/jvrails for more book information.
10
+ #---
11
+ class HomeController < ApplicationController
12
+ def index
13
+ respond_to do |format|
14
+ format.html
15
+ format.csv
16
+ end
17
+ end
18
+
19
+ def only_html; end
20
+
21
+ def another
22
+ render :csv => "index", :filename => "filename_test.csv"
23
+ end
24
+
25
+ def render_elsewhere
26
+ case params[:type]
27
+ when '1'
28
+ render :csv => "home/index", :template => 'users/index'
29
+ when '2'
30
+ render :csv => "users/index", :template => 'users/index'
31
+ when '3'
32
+ render template: "users/index"
33
+ when '4'
34
+ render "users/index"
35
+ else
36
+ render :csv => "index"
37
+ end
38
+ end
39
+
40
+ def render_file_path
41
+ render :csv => Rails.root.join('app','views','users','index')
42
+ end
43
+
44
+ def withpartial
45
+ end
46
+
47
+ def useheader
48
+ respond_to do |format|
49
+ format.csv {
50
+ if params[:set_direct]
51
+ response.headers['Content-Disposition'] = "attachment; filename=\"filename_test.csv\""
52
+ else
53
+ render csv: "useheader", filename: "filename_test.csv"
54
+ end
55
+ }
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ class LikesController < ApplicationController
4
+ # GET /likes
5
+ # GET /likes.json
6
+ def index
7
+ @user = User.find(params[:user_id])
8
+ @likes = @user.likes
9
+
10
+ respond_to do |format|
11
+ format.html # index.html.erb
12
+ format.csv
13
+ end
14
+ end
15
+
16
+ def render_elsewhere
17
+ @user = User.find(params[:user_id])
18
+ render :csv => "index", :template => 'users/index'
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ class UsersController < ApplicationController
4
+ respond_to :csv, :html
5
+ layout Proc.new { |c| return (c.request.format.symbol == :csv ? false : :default )}
6
+
7
+ # GET /users
8
+ # GET /users.json
9
+ def index
10
+ @users = User.all
11
+
12
+ respond_to do |format|
13
+ format.html # index.html.erb
14
+ format.csv
15
+ end
16
+ end
17
+
18
+ def show
19
+ @user = User.find(params[:id])
20
+ respond_with(@user) do |format|
21
+ format.csv { render "respond_with.csv.csvrb" }
22
+ end
23
+ end
24
+
25
+ def send_instructions
26
+ @user = User.find(params[:user_id])
27
+ @user.send_instructions
28
+ render plain: "Email sent"
29
+ end
30
+
31
+ def export
32
+ @user = User.find(params[:id])
33
+ respond_to do |format|
34
+ format.csv do
35
+ render csv: "export", filename: "export_#{@user.id}"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,14 @@
1
+ class Notifier < ActionMailer::Base
2
+ default :from => 'noreply@company.com'
3
+
4
+ def instructions(user)
5
+ @user = user
6
+
7
+ # normal syntax
8
+ csv = render_to_string handlers: [:csvrb], template: 'users/send_instructions', layout: false, formats: [:csv]
9
+ attachments["user_#{user.id}.csv"] = {mime_type: Mime[:csv], content: csv}
10
+
11
+ mail :to => user.email, :subject => 'Instructions'
12
+ end
13
+
14
+ end
@@ -0,0 +1,3 @@
1
+ class Like < ActiveRecord::Base
2
+ belongs_to :user
3
+ end
@@ -0,0 +1,24 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :likes
3
+
4
+ def self.to_csv(enum)
5
+ all.each do |user|
6
+ enum << user.to_csv
7
+ end
8
+ end
9
+
10
+ def send_instructions
11
+ Notifier.instructions(self).deliver
12
+ end
13
+
14
+ def to_csv
15
+ [
16
+ self.name,
17
+ self.last_name,
18
+ self.address,
19
+ self.email,
20
+ self.created_at.to_s,
21
+ self.updated_at.to_s
22
+ ]
23
+ end
24
+ end
@@ -0,0 +1 @@
1
+ csv << ['Cover', 'Sheet']
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ csv << ['Bad', 'spellers', 'of', 'the', 'world', '...']
@@ -0,0 +1,4 @@
1
+ <p>Hey, you can download the csv for this page by clicking the link below:</p>
2
+ <p><%= link_to "csv", home_path("csv") %></p>
3
+ <p><%= link_to "Another", '/another.csv' %></p>
4
+ <p><%= link_to "User header", '/useheader.csv' %></p>
@@ -0,0 +1,2 @@
1
+ <h3>HTML</h3>
2
+ <p>Foo, bar</p>
@@ -0,0 +1 @@
1
+ csv << ['Bad', 'spellers', 'of', 'the', 'world', '...']
@@ -0,0 +1,2 @@
1
+ render :partial => 'cover_sheet', :locals => {:csv => csv}
2
+ csv << ['Bad', 'spellers', 'of', 'the', 'world', '...']
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy 4</title>
5
+ <%= csrf_meta_tags %>
6
+ </head>
7
+ <body>
8
+
9
+ <%= yield %>
10
+
11
+ </body>
12
+ </html>
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy 4</title>
5
+ <%= csrf_meta_tags %>
6
+ </head>
7
+ <body>
8
+
9
+ <%= yield %>
10
+
11
+ </body>
12
+ </html>
@@ -0,0 +1,4 @@
1
+ csv << [@user.name]
2
+ @likes.each do |like|
3
+ csv << [like.name]
4
+ end
@@ -0,0 +1,17 @@
1
+ <h1>Listing likes for <%= @user.name %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ </tr>
7
+
8
+ <% @likes.each do |like| %>
9
+ <tr>
10
+ <td><%= like.name %></td>
11
+ </tr>
12
+ <% end %>
13
+ </table>
14
+
15
+ <br />
16
+
17
+ <%= link_to 'New Like', new_like_path %>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
5
+ </head>
6
+ <body>
7
+ <h1>Instructions</h1>
8
+ <p>
9
+ You have successfully signed up to example.com,
10
+ your username is: <%= @user.email %>.<br/>
11
+ </p>
12
+ <p>Thanks for joining and have a great day!</p>
13
+ </body>
14
+ </html>