csv_magic 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +13 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +76 -0
  7. data/Rakefile +26 -0
  8. data/app/views/csv_magic/import.html.erb +10 -0
  9. data/app/views/csv_magic/import_errors.html.erb +8 -0
  10. data/app/views/csv_magic/mapper.html.erb +42 -0
  11. data/config/locales/de.yml +13 -0
  12. data/csv_magic.gemspec +23 -0
  13. data/lib/csv_magic/controller_actions.rb +87 -0
  14. data/lib/csv_magic/engine.rb +5 -0
  15. data/lib/csv_magic/file_handler.rb +35 -0
  16. data/lib/csv_magic/i18n_helpers.rb +23 -0
  17. data/lib/csv_magic/importer.rb +27 -0
  18. data/lib/csv_magic/reader.rb +38 -0
  19. data/lib/csv_magic/version.rb +3 -0
  20. data/lib/csv_magic.rb +39 -0
  21. data/spec/dummy/Rakefile +7 -0
  22. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  23. data/spec/dummy/app/controllers/people_controller.rb +24 -0
  24. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  25. data/spec/dummy/app/models/person.rb +2 -0
  26. data/spec/dummy/app/views/layouts/application.html.erb +18 -0
  27. data/spec/dummy/app/views/people/index.html.erb +21 -0
  28. data/spec/dummy/config/application.rb +43 -0
  29. data/spec/dummy/config/boot.rb +10 -0
  30. data/spec/dummy/config/database.yml +22 -0
  31. data/spec/dummy/config/environment.rb +5 -0
  32. data/spec/dummy/config/environments/development.rb +30 -0
  33. data/spec/dummy/config/environments/production.rb +60 -0
  34. data/spec/dummy/config/environments/test.rb +39 -0
  35. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  36. data/spec/dummy/config/initializers/inflections.rb +10 -0
  37. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  38. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  39. data/spec/dummy/config/initializers/session_store.rb +8 -0
  40. data/spec/dummy/config/locales/en.yml +5 -0
  41. data/spec/dummy/config/routes.rb +6 -0
  42. data/spec/dummy/config.ru +4 -0
  43. data/spec/dummy/db/migrate/20110808105053_create_people.rb +14 -0
  44. data/spec/dummy/db/test.sqlite3 +0 -0
  45. data/spec/dummy/log/production.log +0 -0
  46. data/spec/dummy/log/server.log +0 -0
  47. data/spec/dummy/public/404.html +26 -0
  48. data/spec/dummy/public/422.html +26 -0
  49. data/spec/dummy/public/500.html +26 -0
  50. data/spec/dummy/public/favicon.ico +0 -0
  51. data/spec/dummy/public/javascripts/application.js +2 -0
  52. data/spec/dummy/public/javascripts/controls.js +965 -0
  53. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  54. data/spec/dummy/public/javascripts/effects.js +1123 -0
  55. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  56. data/spec/dummy/public/javascripts/rails.js +191 -0
  57. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  58. data/spec/dummy/script/rails +6 -0
  59. data/spec/dummy_data.csv +3 -0
  60. data/spec/file_handler_spec.rb +52 -0
  61. data/spec/importer_spec.rb +9 -0
  62. data/spec/integration/get_request_spec.rb +1 -0
  63. data/spec/integration/post_request_spec.rb +13 -0
  64. data/spec/integration/resource_integration_spec.rb +23 -0
  65. data/spec/spec_helper.rb +33 -0
  66. data/spec/test.file +0 -0
  67. metadata +163 -0
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ spec/dummy/tmp
2
+ spec/dummy/log
3
+ spec/dummy/db
4
+ .idea
5
+ *.gem
6
+ .bundle
7
+ Gemfile.lock
8
+ pkg/*
9
+
10
+ /spec/dummy/log/test.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ branches:
6
+ only:
7
+ - master
8
+ before_script:
9
+ - "sh -c 'cd spec/dummy && RAILS_ENV=test bundle exec rake db:migrate'"
10
+ script: "bundle exec rspec spec"
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in csv_magic.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ if !ENV["CI"]
8
+ gem 'ruby-debug-base19', '~> 0.11.26', :platform => :ruby_19
9
+ gem 'linecache19', '~> 0.5.13', :platform => :ruby_19
10
+ gem 'ruby-debug19', '~> 0.11.6', :require => 'ruby-debug', :platform => :ruby_19
11
+ gem 'ruby-debug', :platform => :ruby_18
12
+ end
13
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ ## Description
2
+
3
+ This gem adds an import action in every controller you like to be able to handle csv imports.
4
+ It includes the complete workflow:
5
+
6
+ * CSV file upload
7
+ * Field mapping with review
8
+ * Creating model records
9
+
10
+ ## Requirements
11
+
12
+ Rails >= 3.1.x and Ruby >= 1.9.x
13
+
14
+ ## Installation
15
+
16
+ Install as gem:
17
+
18
+ $ gem install csv_magic
19
+
20
+ Or in your apps `Gemfile`:
21
+
22
+ gem 'csv_magic', :git => 'git://github.com/magiclabs/csv_magic.git'
23
+
24
+ ## Usage
25
+
26
+ ### Set up a new route to point to the import action (get & post will be needed!):
27
+
28
+ # routes.rb
29
+ resources :myresource do
30
+ get 'import', :on => :collection
31
+ post 'import', :on => :collection
32
+ end
33
+
34
+ ### Include it in your Controller:
35
+
36
+ include CSVMagic::ControllerActions
37
+
38
+ ### Set up the fields to map to:
39
+
40
+ # your_controller.rb
41
+ csv_magic_config(
42
+ :mapping => {
43
+ "Firstname" => :firstname,
44
+ "Lastname" => :lastname
45
+ }
46
+ )
47
+
48
+ **See also the implementation in `spec/dummy` app!**
49
+
50
+ ## Customizing
51
+
52
+ Nearly any part of the gem can be overridden!
53
+
54
+ ### The views
55
+
56
+ To override the views place a `csv_magic` folder inside your apps `app/views` folder.
57
+
58
+ * `import.html.erb` => The import view, where the form is placed on
59
+ * `mapper.html.erb` => The mapper view, where the mapping happens
60
+ * `import_errors.html.erb` => The import errors view, where import errors while be shown
61
+
62
+ ### The actions
63
+
64
+ To override the actions just define the method you want to override inside your controller.
65
+
66
+ Just have a look into `lib/controller_actions.rb` file to see the methods.
67
+
68
+ ## Thanks
69
+
70
+ This gem is heavily based on [Andrew Timberlake's map-fields-gem](http://github.com/internuity/map-fields).
71
+
72
+ Nevertheless we didn't fork it, because the changes are too fundamental.
73
+
74
+ ## License
75
+
76
+ MIT License. Copyright 2012 [magic labs*](http://magiclabs.de)
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ #encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'bundler/gem_tasks'
4
+ begin
5
+ require 'bundler/setup'
6
+ rescue LoadError
7
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
8
+ end
9
+
10
+ require 'rake'
11
+ require 'rake/rdoctask'
12
+
13
+ require 'rspec/core'
14
+ require 'rspec/core/rake_task'
15
+
16
+ RSpec::Core::RakeTask.new(:spec)
17
+
18
+ task :default => :spec
19
+
20
+ Rake::RDocTask.new(:rdoc) do |rdoc|
21
+ rdoc.rdoc_dir = 'rdoc'
22
+ rdoc.title = 'CSVMagicTest'
23
+ rdoc.options << '--line-numbers' << '--inline-source'
24
+ rdoc.rdoc_files.include('README.rdoc')
25
+ rdoc.rdoc_files.include('lib/**/*.rb')
26
+ end
@@ -0,0 +1,10 @@
1
+ <h1><%= t(:import_csv_file) %></h1>
2
+
3
+ <p><%= t(:please_choose_a_csv_file) %>:</p>
4
+
5
+ <%= form_tag(url_for(:action => 'import'), :multipart => true) do %>
6
+ <div class="field">
7
+ <%= file_field_tag 'file' %>
8
+ <%= submit_tag t(:import) %>
9
+ </div>
10
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <div class="csv_magic_import_errros">
2
+ <h2><%= t(:import_errors) %>:</h2>
3
+ <ol>
4
+ <%- @csv_import_errors.each do |error| -%>
5
+ <li><%= error.full_messages %></li>
6
+ <%- end -%>
7
+ </ol>
8
+ </div>
@@ -0,0 +1,42 @@
1
+ <h1><%= t(:import_csv_file) %></h1>
2
+
3
+ <p><%= t(:please_map_columns) %></p>
4
+
5
+ <%= form_tag nil, :id => 'map_fields_form', :method => :post do -%>
6
+ <%= hidden_field_tag :filename, @mapper.filename %>
7
+ <div class="map_fields">
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <%- header = @raw_data.first -%>
12
+ <%- header.size.times do |column_index| -%>
13
+ <th>
14
+ <%= select_tag("fields[#{column_index + 1}]", options_for_select(
15
+ @mapper.map_fields,
16
+ @mapper.map_fields[header[column_index]]
17
+ ), :include_blank => true, :class => 'field_options') %>
18
+ </th>
19
+ <%- end -%>
20
+ </tr>
21
+ </thead>
22
+ <tbody>
23
+ <%- @raw_data[0..5].each do |row| -%>
24
+ <tr>
25
+ <%- row.each do |column| -%>
26
+ <td><%= h(column) -%></td>
27
+ <%- end -%>
28
+ </tr>
29
+ <%- end -%>
30
+ </tbody>
31
+ </table>
32
+ </div>
33
+ <div class="option">
34
+ <p>
35
+ <%= check_box_tag 'ignore_first_row', '1', true %>
36
+ <%= label_tag 'ignore_first_row', t(:ignore_first_row) %>
37
+ </p>
38
+ </div>
39
+ <div class="action">
40
+ <%= submit_tag t(:import) %>
41
+ </div>
42
+ <%- end -%>
@@ -0,0 +1,13 @@
1
+ de:
2
+ csv_magic:
3
+ csv_file_has_wrong_format: "Fehlerhaft formatierte CSV-Datei: %{error}"
4
+ errors_while_importing: "Beim Importieren sind Fehler aufgetreten!"
5
+ file_not_on_server_any_more: 'Datei nicht mehr auf dem Server. Bitte erneut hochladen!'
6
+ ignore_first_row: 'Erste Zeile auslassen (Titelzeile)'
7
+ import: 'Importieren'
8
+ import_csv_file: 'CSV importieren'
9
+ import_errors: 'Folgende Fehler sind aufgetreten'
10
+ please_choose_a_csv_file: 'Bitte wählen Sie eine CSV-Datei aus'
11
+ please_map_columns: 'Bitte Felder zuweisen'
12
+ please_upload_a_csv_file: 'Bitte eine CSV-Datei hochladen.'
13
+ successfully_imported_data: 'Die Daten wurden erfolgreich importiert.'
data/csv_magic.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "csv_magic/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "csv_magic"
7
+ s.version = CSVMagic::VERSION
8
+ s.authors = ["Marc Schettke", "Thomas von Deyen"]
9
+ s.email = ["mail@magiclabs.de"]
10
+ s.homepage = "https://github.com/magiclabs/csv_magic"
11
+ s.summary = %q{Adds some CSV magic into your app.}
12
+ s.description = %q{Provides controller actions, views and field mapping for data from a csv file.}
13
+ s.rubyforge_project = "csv_magic"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_development_dependency 'rails', ['~> 3.1.4']
20
+ s.add_development_dependency 'rspec-rails', ["~> 2.8.0"]
21
+ s.add_development_dependency 'sqlite3', ["~> 1.3.5"]
22
+ s.add_development_dependency 'capybara', ['>= 0.4.0']
23
+ end
@@ -0,0 +1,87 @@
1
+ module CSVMagic
2
+ module ControllerActions
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.csv_magic_config
7
+ base.send(:include, I18nHelpers)
8
+ end
9
+
10
+ module ClassMethods
11
+ def csv_magic_config( options = {} )
12
+ defaults = {
13
+ :action => :import,
14
+ :mapping => {},
15
+ :file_field => :file
16
+ }
17
+ options = defaults.merge(options)
18
+ write_inheritable_attribute(:map_fields_options, options)
19
+ end
20
+ end
21
+
22
+ def import
23
+ if request.post?
24
+ handle_csv_post_request
25
+ else
26
+ render_csv_import_form
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def create_resource_items_from_csv(resource_class)
33
+ @csv_import_errors = []
34
+ reader = Reader.new(params)
35
+ reader.each do |row|
36
+ resource = resource_class.new(row)
37
+ unless resource.save
38
+ @csv_import_errors.push resource.errors
39
+ end
40
+ end
41
+ reader.remove_file if @csv_import_errors.empty?
42
+ end
43
+
44
+ def resource_class
45
+ @resource_name ||= self.class.name.gsub(/Controller|Admin/, '').gsub(/:{4}/, '::').singularize
46
+ @resource_class ||= @resource_name.constantize
47
+ end
48
+
49
+ def render_csv_import_form
50
+ render 'csv_magic/import'
51
+ end
52
+
53
+ def handle_csv_post_request
54
+ # already mapped
55
+ if params[:fields]
56
+ create_resource_items_from_csv(resource_class)
57
+ if @csv_import_errors.empty?
58
+ flash[:notice] = t(:successfully_imported_data)
59
+ redirect_to :action => :index
60
+ else
61
+ flash[:warning] = t(:errors_while_importing)
62
+ render 'csv_magic/import_errors'
63
+ end
64
+ #no mapping yet
65
+ else
66
+ @mapper = Importer.new(params, self.class.read_inheritable_attribute(:map_fields_options))
67
+ @raw_data = @mapper.raw_data
68
+ render 'csv_magic/mapper'
69
+ end
70
+ rescue MissingFileContentsError
71
+ flash[:warning] = t(:please_upload_a_csv_file)
72
+ render_csv_import_form
73
+ rescue ::CSV::MalformedCSVError => e
74
+ flash[:warning] = t(:csv_file_has_wrong_format) % {:error => e.message}
75
+ render_csv_import_form
76
+ rescue ::Errno::ENOENT
77
+ flash[:warning] = t(:file_not_on_server_any_more)
78
+ render_csv_import_form
79
+ rescue Exception => e
80
+ flash[:warning] = e.message
81
+ logger.error(e.message)
82
+ logger.error(e.backtrace.join("\n"))
83
+ render_csv_import_form
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,5 @@
1
+ module CSVMagic
2
+ class Engine < Rails::Engine
3
+
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ module CSVMagic
2
+ class FileHandler
3
+
4
+ attr_reader :path, :filename
5
+
6
+ def initialize()
7
+ @path = ::File.join(::Rails.root.to_s, "tmp")
8
+ end
9
+
10
+ def save_temp_file(tempfile)
11
+ @filename = unique_filename
12
+ ::FileUtils.copy_file(tempfile.path, file_path)
13
+ ::File.exists?(file_path)
14
+ end
15
+
16
+ def load_file(filename)
17
+ @filename = filename
18
+ ::File.exist?(file_path)
19
+ end
20
+
21
+ def remove_file
22
+ ::File.delete(file_path)
23
+ end
24
+
25
+ def file_path
26
+ ::File.join(@path, @filename)
27
+ end
28
+
29
+ def unique_filename
30
+ t = ::Time.now.strftime("%Y%m%d")
31
+ "#{t}-#{$$}-#{rand(0x100000000000000).to_s(36)}"
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module CSVMagic
2
+ module I18nHelpers
3
+
4
+ def self.included(controller)
5
+ if controller.respond_to?(:helper_method)
6
+ controller.send(:helper_method, [:t])
7
+ end
8
+ end
9
+
10
+ # This is a proxy to the ::I18n.t method with an csv_magic scope.
11
+ #
12
+ # === NOTE:
13
+ #
14
+ # The keys are scoped into +csv_magic+ namespace.
15
+ # Even if you pass a scope this is scoped under +csv_magic+.
16
+ #
17
+ def t(key, options={})
18
+ scope = options[:scope].blank? ? 'csv_magic' : "csv_magic.#{options.delete(:scope)}"
19
+ ::I18n.t(key, {:scope => scope, :default => key.to_s.humanize}.merge(options))
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module CSVMagic
2
+ class Importer
3
+ attr_reader :map_fields, :filename
4
+
5
+ def initialize(params, options)
6
+ @file_handler = FileHandler.new()
7
+
8
+ if @file_handler.save_temp_file(params[options[:file_field]])
9
+ set_attributes_from_valid_file(options)
10
+ else
11
+ raise MissingFileContentsError
12
+ end
13
+ end
14
+
15
+ def raw_data
16
+ ::CSV.read(@file_handler.file_path, CSVMagic.options)
17
+ end
18
+
19
+ private
20
+
21
+ def set_attributes_from_valid_file(options)
22
+ @filename = @file_handler.filename
23
+ @map_fields = options[:mapping]
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ module CSVMagic
2
+ class Reader
3
+
4
+ def initialize(params)
5
+ @file_handler = FileHandler.new
6
+ @file_handler.load_file(params[:filename])
7
+
8
+ @file_path = @file_handler.file_path
9
+ @ignore_first_row = params[:ignore_first_row]
10
+ @mapping = {}
11
+ params[:fields].each do |k, v|
12
+ unless v.empty?
13
+ @mapping[v.downcase.to_sym] = k.to_i - 1
14
+ end
15
+ end
16
+ end
17
+
18
+ def each
19
+ row_number = 1
20
+ ::CSV.foreach(@file_path, CSVMagic.options) do |csv_row|
21
+ unless row_number == 1 && @ignore_first_row
22
+ row = {}
23
+ @mapping.each do |k, v|
24
+ row[k] = csv_row[v]
25
+ end
26
+ row.class.send(:define_method, :number) { row_number }
27
+ yield(row)
28
+ end
29
+ row_number += 1
30
+ end
31
+ end
32
+
33
+ def remove_file
34
+ @file_handler.remove_file
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module CSVMagic
2
+ VERSION = "0.2.0"
3
+ end
data/lib/csv_magic.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'csv'
2
+ require "csv_magic/version"
3
+ require 'csv_magic/i18n_helpers'
4
+ require 'csv_magic/controller_actions'
5
+ require 'csv_magic/engine'
6
+ require 'csv_magic/importer'
7
+ require 'csv_magic/reader'
8
+ require 'csv_magic/file_handler'
9
+
10
+ module CSVMagic
11
+
12
+ class InconsistentStateError < StandardError
13
+ end
14
+
15
+ class MissingFileContentsError < StandardError
16
+ end
17
+
18
+ @@options = {
19
+ :col_sep => ";",
20
+ :row_sep => :auto,
21
+ :quote_char => '"',
22
+ :converters => nil,
23
+ :unconverted_fields => nil,
24
+ :headers => false,
25
+ :return_headers => false,
26
+ :header_converters => nil,
27
+ :skip_blanks => false,
28
+ :force_quotes => false
29
+ }.freeze
30
+
31
+ def self.options
32
+ @@options
33
+ end
34
+
35
+ def self.options=(options)
36
+ @@options = options
37
+ end
38
+
39
+ end
@@ -0,0 +1,7 @@
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
+ require 'rake'
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,24 @@
1
+ class PeopleController < ApplicationController
2
+
3
+ include CSVMagic::ControllerActions
4
+
5
+ csv_magic_config(
6
+ :mapping => {
7
+ "Firstname" => :firstname,
8
+ "Lastname" => :lastname
9
+ }
10
+ )
11
+
12
+ # GET /people
13
+ def index
14
+ @people = Person.all
15
+ end
16
+
17
+ # DELETE /people/1
18
+ def destroy
19
+ @person = Person.find(params[:id])
20
+ @person.destroy
21
+ redirect_to(people_url)
22
+ end
23
+
24
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ class Person < ActiveRecord::Base
2
+ end
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag :all %>
6
+ <%= javascript_include_tag :defaults %>
7
+ <%= csrf_meta_tag %>
8
+ </head>
9
+ <body>
10
+ <p id="flash">
11
+ <%= flash[:notice] %>
12
+ <%= flash[:warning] %>
13
+ </p>
14
+
15
+ <%= yield %>
16
+
17
+ </body>
18
+ </html>
@@ -0,0 +1,21 @@
1
+ <h1>Listing People</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Lastname</th>
6
+ <th>Firstname</th>
7
+ <th></th>
8
+ </tr>
9
+
10
+ <% @people.each do |person| %>
11
+ <tr>
12
+ <td><%= person.lastname %></td>
13
+ <td><%= person.firstname %></td>
14
+ <td><%= link_to 'Destroy', person, :confirm => 'Are you sure?', :method => :delete %></td>
15
+ </tr>
16
+ <% end %>
17
+ </table>
18
+
19
+ <br />
20
+
21
+ <%= link_to 'Import People!', import_people_path %>
@@ -0,0 +1,43 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require
6
+ require "csv_magic"
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Custom directories with classes and modules you want to be autoloadable.
15
+ # config.autoload_paths += %W(#{config.root}/extras)
16
+
17
+ # Only load the plugins named here, in the order given (default is alphabetical).
18
+ # :all can be used as a placeholder for all plugins not explicitly named.
19
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
20
+
21
+ # Activate observers that should always be running.
22
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
23
+
24
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
25
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
26
+ # config.time_zone = 'Central Time (US & Canada)'
27
+
28
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
29
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
30
+
31
+ # Configure the default encoding used in templates for Ruby 1.9.
32
+ config.encoding = "utf-8"
33
+
34
+ # Configure sensitive parameters which will be filtered from the log file.
35
+ # config.filter_parameters += [:password]
36
+
37
+ # Enable the asset pipeline
38
+ config.assets.enabled = true
39
+
40
+ # Version of your assets, change this if you want to expire all your assets
41
+ config.assets.version = '1.0'
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ if File.exist?(gemfile)
5
+ ENV['BUNDLE_GEMFILE'] = gemfile
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ $:.unshift File.expand_path('../../../../lib', __FILE__)