├── README.md ├── store-after ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app │ ├── assets │ │ ├── javascripts │ │ │ ├── application.js │ │ │ └── products.js.coffee │ │ └── stylesheets │ │ │ ├── application.css │ │ │ ├── layout.css.scss │ │ │ └── products.css.scss │ ├── controllers │ │ ├── application_controller.rb │ │ └── products_controller.rb │ ├── helpers │ │ ├── application_helper.rb │ │ └── products_helper.rb │ ├── mailers │ │ └── .gitkeep │ ├── models │ │ ├── .gitkeep │ │ └── product.rb │ └── views │ │ ├── layouts │ │ └── application.html.erb │ │ └── products │ │ ├── index.html.erb │ │ └── index.xls.erb ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── backtrace_silencers.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── secret_token.rb │ │ ├── session_store.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ └── routes.rb ├── db │ ├── migrate │ │ └── 20120701210336_create_products.rb │ ├── schema.rb │ └── seeds.rb ├── doc │ └── README_FOR_APP ├── lib │ ├── assets │ │ └── .gitkeep │ └── tasks │ │ └── .gitkeep ├── log │ └── .gitkeep ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── favicon.ico │ └── robots.txt ├── script │ └── rails ├── test │ ├── fixtures │ │ ├── .gitkeep │ │ └── products.yml │ ├── functional │ │ ├── .gitkeep │ │ └── products_controller_test.rb │ ├── integration │ │ └── .gitkeep │ ├── performance │ │ └── browsing_test.rb │ ├── test_helper.rb │ └── unit │ │ ├── .gitkeep │ │ ├── helpers │ │ └── products_helper_test.rb │ │ └── product_test.rb └── vendor │ ├── assets │ ├── javascripts │ │ └── .gitkeep │ └── stylesheets │ │ └── .gitkeep │ └── plugins │ └── .gitkeep ├── store-before ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app │ ├── assets │ │ ├── javascripts │ │ │ ├── application.js │ │ │ └── products.js.coffee │ │ └── stylesheets │ │ │ ├── application.css │ │ │ ├── layout.css.scss │ │ │ └── products.css.scss │ ├── controllers │ │ ├── application_controller.rb │ │ └── products_controller.rb │ ├── helpers │ │ ├── application_helper.rb │ │ └── products_helper.rb │ ├── mailers │ │ └── .gitkeep │ ├── models │ │ ├── .gitkeep │ │ └── product.rb │ └── views │ │ ├── layouts │ │ └── application.html.erb │ │ └── products │ │ ├── index.html.erb │ │ └── index.xls.erb ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── backtrace_silencers.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── secret_token.rb │ │ ├── session_store.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ └── routes.rb ├── db │ ├── migrate │ │ └── 20120701210336_create_products.rb │ ├── schema.rb │ └── seeds.rb ├── doc │ └── README_FOR_APP ├── lib │ ├── assets │ │ └── .gitkeep │ └── tasks │ │ └── .gitkeep ├── log │ └── .gitkeep ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── favicon.ico │ └── robots.txt ├── script │ └── rails ├── test │ ├── fixtures │ │ ├── .gitkeep │ │ └── products.yml │ ├── functional │ │ ├── .gitkeep │ │ └── products_controller_test.rb │ ├── integration │ │ └── .gitkeep │ ├── performance │ │ └── browsing_test.rb │ ├── test_helper.rb │ └── unit │ │ ├── .gitkeep │ │ ├── helpers │ │ └── products_helper_test.rb │ │ └── product_test.rb └── vendor │ ├── assets │ ├── javascripts │ │ └── .gitkeep │ └── stylesheets │ │ └── .gitkeep │ └── plugins │ └── .gitkeep └── store-with-validations ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app ├── assets │ ├── javascripts │ │ ├── application.js │ │ ├── product_imports.js.coffee │ │ └── products.js.coffee │ └── stylesheets │ │ ├── application.css │ │ ├── layout.css.scss │ │ ├── product_imports.css.scss │ │ └── products.css.scss ├── controllers │ ├── application_controller.rb │ ├── product_imports_controller.rb │ └── products_controller.rb ├── helpers │ ├── application_helper.rb │ ├── product_imports_helper.rb │ └── products_helper.rb ├── mailers │ └── .gitkeep ├── models │ ├── .gitkeep │ ├── product.rb │ └── product_import.rb └── views │ ├── layouts │ └── application.html.erb │ ├── product_imports │ └── new.html.erb │ └── products │ ├── index.html.erb │ └── index.xls.erb ├── config.ru ├── config ├── application.rb ├── boot.rb ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── backtrace_silencers.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── secret_token.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml └── routes.rb ├── db ├── migrate │ └── 20120701210336_create_products.rb ├── schema.rb └── seeds.rb ├── doc └── README_FOR_APP ├── lib ├── assets │ └── .gitkeep └── tasks │ └── .gitkeep ├── log └── .gitkeep ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico └── robots.txt ├── script └── rails ├── test ├── fixtures │ ├── .gitkeep │ └── products.yml ├── functional │ ├── .gitkeep │ ├── product_imports_controller_test.rb │ └── products_controller_test.rb ├── integration │ └── .gitkeep ├── performance │ └── browsing_test.rb ├── test_helper.rb └── unit │ ├── .gitkeep │ ├── helpers │ ├── product_imports_helper_test.rb │ └── products_helper_test.rb │ └── product_test.rb └── vendor ├── assets ├── javascripts │ └── .gitkeep └── stylesheets │ └── .gitkeep └── plugins └── .gitkeep /README.md: -------------------------------------------------------------------------------- 1 | # RailsCasts Episode #396: Importing CSV and Excel 2 | 3 | http://railscasts.com/episodes/396-importing-csv-and-excel 4 | 5 | Requires Ruby 1.9.2 or higher. 6 | -------------------------------------------------------------------------------- /store-after/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile ~/.gitignore_global 6 | 7 | # Ignore bundler config 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/*.log 15 | /tmp 16 | -------------------------------------------------------------------------------- /store-after/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rails', '3.2.9' 4 | 5 | # Bundle edge Rails instead: 6 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 7 | 8 | gem 'sqlite3' 9 | 10 | 11 | # Gems used only for assets and not required 12 | # in production environments by default. 13 | group :assets do 14 | gem 'sass-rails', '~> 3.2.3' 15 | gem 'coffee-rails', '~> 3.2.1' 16 | 17 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 18 | # gem 'therubyracer', :platforms => :ruby 19 | 20 | gem 'uglifier', '>= 1.0.3' 21 | end 22 | 23 | gem 'jquery-rails' 24 | 25 | # To use ActiveModel has_secure_password 26 | # gem 'bcrypt-ruby', '~> 3.0.0' 27 | 28 | # To use Jbuilder templates for JSON 29 | # gem 'jbuilder' 30 | 31 | # Use unicorn as the app server 32 | # gem 'unicorn' 33 | 34 | # Deploy with Capistrano 35 | # gem 'capistrano' 36 | 37 | # To use debugger 38 | # gem 'debugger' 39 | 40 | gem 'roo' 41 | -------------------------------------------------------------------------------- /store-after/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (3.2.9) 5 | actionpack (= 3.2.9) 6 | mail (~> 2.4.4) 7 | actionpack (3.2.9) 8 | activemodel (= 3.2.9) 9 | activesupport (= 3.2.9) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | journey (~> 1.0.4) 13 | rack (~> 1.4.0) 14 | rack-cache (~> 1.2) 15 | rack-test (~> 0.6.1) 16 | sprockets (~> 2.2.1) 17 | activemodel (3.2.9) 18 | activesupport (= 3.2.9) 19 | builder (~> 3.0.0) 20 | activerecord (3.2.9) 21 | activemodel (= 3.2.9) 22 | activesupport (= 3.2.9) 23 | arel (~> 3.0.2) 24 | tzinfo (~> 0.3.29) 25 | activeresource (3.2.9) 26 | activemodel (= 3.2.9) 27 | activesupport (= 3.2.9) 28 | activesupport (3.2.9) 29 | i18n (~> 0.6) 30 | multi_json (~> 1.0) 31 | arel (3.0.2) 32 | builder (3.0.4) 33 | choice (0.1.6) 34 | coffee-rails (3.2.2) 35 | coffee-script (>= 2.2.0) 36 | railties (~> 3.2.0) 37 | coffee-script (2.2.0) 38 | coffee-script-source 39 | execjs 40 | coffee-script-source (1.4.0) 41 | erubis (2.7.0) 42 | execjs (1.4.0) 43 | multi_json (~> 1.0) 44 | faraday (0.8.4) 45 | multipart-post (~> 1.1) 46 | google-spreadsheet-ruby (0.3.0) 47 | google_drive (>= 0.3.0) 48 | google_drive (0.3.2) 49 | nokogiri (>= 1.4.4, != 1.5.2, != 1.5.1) 50 | oauth (>= 0.3.6) 51 | oauth2 (>= 0.5.0) 52 | hike (1.2.1) 53 | httpauth (0.2.0) 54 | i18n (0.6.1) 55 | journey (1.0.4) 56 | jquery-rails (2.1.4) 57 | railties (>= 3.0, < 5.0) 58 | thor (>= 0.14, < 2.0) 59 | json (1.7.5) 60 | jwt (0.1.5) 61 | multi_json (>= 1.0) 62 | log4r (1.1.10) 63 | mail (2.4.4) 64 | i18n (>= 0.4.0) 65 | mime-types (~> 1.16) 66 | treetop (~> 1.4.8) 67 | mime-types (1.19) 68 | multi_json (1.4.0) 69 | multipart-post (1.1.5) 70 | nokogiri (1.5.5) 71 | oauth (0.4.7) 72 | oauth2 (0.8.0) 73 | faraday (~> 0.8) 74 | httpauth (~> 0.1) 75 | jwt (~> 0.1.4) 76 | multi_json (~> 1.0) 77 | rack (~> 1.2) 78 | polyglot (0.3.3) 79 | rack (1.4.1) 80 | rack-cache (1.2) 81 | rack (>= 0.4) 82 | rack-ssl (1.3.2) 83 | rack 84 | rack-test (0.6.2) 85 | rack (>= 1.0) 86 | rails (3.2.9) 87 | actionmailer (= 3.2.9) 88 | actionpack (= 3.2.9) 89 | activerecord (= 3.2.9) 90 | activeresource (= 3.2.9) 91 | activesupport (= 3.2.9) 92 | bundler (~> 1.0) 93 | railties (= 3.2.9) 94 | railties (3.2.9) 95 | actionpack (= 3.2.9) 96 | activesupport (= 3.2.9) 97 | rack-ssl (~> 1.3.2) 98 | rake (>= 0.8.7) 99 | rdoc (~> 3.4) 100 | thor (>= 0.14.6, < 2.0) 101 | rake (10.0.2) 102 | rdoc (3.12) 103 | json (~> 1.4) 104 | roo (1.10.1) 105 | choice (>= 0.1.4) 106 | google-spreadsheet-ruby (>= 0.1.5) 107 | nokogiri (>= 1.5.0) 108 | rubyzip (>= 0.9.4) 109 | spreadsheet (> 0.6.4) 110 | todonotes (>= 0.1.0) 111 | ruby-ole (1.2.11.5) 112 | rubyzip (0.9.9) 113 | sass (3.2.3) 114 | sass-rails (3.2.5) 115 | railties (~> 3.2.0) 116 | sass (>= 3.1.10) 117 | tilt (~> 1.3) 118 | spreadsheet (0.7.5) 119 | ruby-ole (>= 1.0) 120 | sprockets (2.2.2) 121 | hike (~> 1.2) 122 | multi_json (~> 1.0) 123 | rack (~> 1.0) 124 | tilt (~> 1.1, != 1.3.0) 125 | sqlite3 (1.3.6) 126 | thor (0.16.0) 127 | tilt (1.3.3) 128 | todonotes (0.1.1) 129 | log4r 130 | treetop (1.4.12) 131 | polyglot 132 | polyglot (>= 0.3.1) 133 | tzinfo (0.3.35) 134 | uglifier (1.3.0) 135 | execjs (>= 0.3.0) 136 | multi_json (~> 1.0, >= 1.0.2) 137 | 138 | PLATFORMS 139 | ruby 140 | 141 | DEPENDENCIES 142 | coffee-rails (~> 3.2.1) 143 | jquery-rails 144 | rails (= 3.2.9) 145 | roo 146 | sass-rails (~> 3.2.3) 147 | sqlite3 148 | uglifier (>= 1.0.3) 149 | -------------------------------------------------------------------------------- /store-after/README.md: -------------------------------------------------------------------------------- 1 | # RailsCasts Example Application 2 | 3 | Run these commands to try it out. 4 | 5 | ``` 6 | bundle 7 | rake db:setup 8 | rails s 9 | ``` 10 | 11 | Requires Ruby 1.9.2 or later to run. 12 | -------------------------------------------------------------------------------- /store-after/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Store::Application.load_tasks 8 | -------------------------------------------------------------------------------- /store-after/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 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 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | -------------------------------------------------------------------------------- /store-after/app/assets/javascripts/products.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /store-after/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 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 top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /store-after/app/assets/stylesheets/layout.css.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | background-color: #4B7399; 3 | font-family: Verdana, Helvetica, Arial; 4 | font-size: 14px; 5 | } 6 | 7 | a img { 8 | border: none; 9 | } 10 | 11 | a { 12 | color: #0000FF; 13 | } 14 | 15 | .clear { 16 | clear: both; 17 | height: 0; 18 | overflow: hidden; 19 | } 20 | 21 | #container { 22 | width: 80%; 23 | margin: 0 auto; 24 | background-color: #FFF; 25 | padding: 20px 40px; 26 | border: solid 1px black; 27 | margin-top: 20px; 28 | } 29 | 30 | #flash_notice, #flash_error, #flash_alert { 31 | padding: 5px 8px; 32 | margin: 10px 0; 33 | } 34 | 35 | #flash_notice { 36 | background-color: #CFC; 37 | border: solid 1px #6C6; 38 | } 39 | 40 | #flash_error, #flash_alert { 41 | background-color: #FCC; 42 | border: solid 1px #C66; 43 | } 44 | 45 | .field_with_errors { 46 | display: inline; 47 | } 48 | 49 | .error_messages { 50 | width: 400px; 51 | border: 2px solid #CF0000; 52 | padding: 0px; 53 | padding-bottom: 12px; 54 | margin-bottom: 20px; 55 | background-color: #f0f0f0; 56 | font-size: 12px; 57 | } 58 | 59 | .error_messages h2 { 60 | text-align: left; 61 | font-weight: bold; 62 | padding: 5px 10px; 63 | font-size: 12px; 64 | margin: 0; 65 | background-color: #c00; 66 | color: #fff; 67 | } 68 | 69 | .error_messages p { 70 | margin: 8px 10px; 71 | } 72 | 73 | .error_messages ul { 74 | margin-bottom: 0; 75 | } 76 | 77 | form .field, form .actions { 78 | margin: 12px 0; 79 | } 80 | -------------------------------------------------------------------------------- /store-after/app/assets/stylesheets/products.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the products controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | table td, table th { 5 | padding-right: 20px; 6 | padding-bottom: 5px; 7 | text-align: left; 8 | &:last-child { 9 | text-align: right; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /store-after/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /store-after/app/controllers/products_controller.rb: -------------------------------------------------------------------------------- 1 | class ProductsController < ApplicationController 2 | def index 3 | @products = Product.order(:name) 4 | respond_to do |format| 5 | format.html 6 | format.csv { send_data @products.to_csv } 7 | format.xls # { send_data @products.to_csv(col_sep: "\t") } 8 | end 9 | end 10 | 11 | def import 12 | Product.import(params[:file]) 13 | redirect_to root_url, notice: "Products imported." 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /store-after/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /store-after/app/helpers/products_helper.rb: -------------------------------------------------------------------------------- 1 | module ProductsHelper 2 | end 3 | -------------------------------------------------------------------------------- /store-after/app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/app/mailers/.gitkeep -------------------------------------------------------------------------------- /store-after/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/app/models/.gitkeep -------------------------------------------------------------------------------- /store-after/app/models/product.rb: -------------------------------------------------------------------------------- 1 | class Product < ActiveRecord::Base 2 | attr_accessible :name, :price, :released_on 3 | 4 | validates_presence_of :price 5 | 6 | def self.to_csv(options = {}) 7 | CSV.generate(options) do |csv| 8 | csv << column_names 9 | all.each do |product| 10 | csv << product.attributes.values_at(*column_names) 11 | end 12 | end 13 | end 14 | 15 | def self.import(file) 16 | spreadsheet = open_spreadsheet(file) 17 | header = spreadsheet.row(1) 18 | (2..spreadsheet.last_row).each do |i| 19 | row = Hash[[header, spreadsheet.row(i)].transpose] 20 | product = find_by_id(row["id"]) || new 21 | product.attributes = row.to_hash.slice(*accessible_attributes) 22 | product.save! 23 | end 24 | end 25 | 26 | def self.open_spreadsheet(file) 27 | case File.extname(file.original_filename) 28 | when ".csv" then Csv.new(file.path, nil, :ignore) 29 | when ".xls" then Excel.new(file.path, nil, :ignore) 30 | when ".xlsx" then Excelx.new(file.path, nil, :ignore) 31 | else raise "Unknown file type: #{file.original_filename}" 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /store-after/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Products 5 | <%= stylesheet_link_tag "application", media: "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tag %> 8 | 9 | 10 |
11 | <% flash.each do |name, msg| %> 12 | <%= content_tag :div, msg, id: "flash_#{name}" %> 13 | <% end %> 14 | <%= yield %> 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /store-after/app/views/products/index.html.erb: -------------------------------------------------------------------------------- 1 |

Products

2 | 3 |

4 | Download: 5 | <%= link_to "CSV", products_path(format: "csv") %> | 6 | <%= link_to "Excel", products_path(format: "xls") %> 7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <% @products.each do |product| %> 16 | 17 | 18 | 19 | 20 | 21 | <% end %> 22 |
Product NameRelease DatePrice
<%= product.name %><%= product.released_on.strftime("%B %e, %Y") %><%= number_to_currency(product.price) %>
23 | 24 |

Import Products

25 | 26 | <%= form_tag import_products_path, multipart: true do %> 27 | <%= file_field_tag :file %> 28 | <%= submit_tag "Import" %> 29 | <% end %> 30 | -------------------------------------------------------------------------------- /store-after/app/views/products/index.xls.erb: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | ID 11 | Name 12 | Release Date 13 | Price 14 | 15 | <% @products.each do |product| %> 16 | 17 | <%= product.id %> 18 | <%= product.name %> 19 | <%= product.released_on %> 20 | <%= product.price %> 21 | 22 | <% end %> 23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /store-after/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Store::Application 5 | -------------------------------------------------------------------------------- /store-after/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'csv' 4 | require 'iconv' 5 | require 'rails/all' 6 | 7 | if defined?(Bundler) 8 | # If you precompile assets before deploying to production, use this line 9 | Bundler.require(*Rails.groups(:assets => %w(development test))) 10 | # If you want your assets lazily compiled in production, use this line 11 | # Bundler.require(:default, :assets, Rails.env) 12 | end 13 | 14 | module Store 15 | class Application < Rails::Application 16 | # Settings in config/environments/* take precedence over those specified here. 17 | # Application configuration should go into files in config/initializers 18 | # -- all .rb files in that directory are automatically loaded. 19 | 20 | # Custom directories with classes and modules you want to be autoloadable. 21 | # config.autoload_paths += %W(#{config.root}/extras) 22 | 23 | # Only load the plugins named here, in the order given (default is alphabetical). 24 | # :all can be used as a placeholder for all plugins not explicitly named. 25 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 26 | 27 | # Activate observers that should always be running. 28 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 29 | 30 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 31 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 32 | # config.time_zone = 'Central Time (US & Canada)' 33 | 34 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 35 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 36 | # config.i18n.default_locale = :de 37 | 38 | # Configure the default encoding used in templates for Ruby 1.9. 39 | config.encoding = "utf-8" 40 | 41 | # Configure sensitive parameters which will be filtered from the log file. 42 | config.filter_parameters += [:password] 43 | 44 | # Enable escaping HTML in JSON. 45 | config.active_support.escape_html_entities_in_json = true 46 | 47 | # Use SQL instead of Active Record's schema dumper when creating the database. 48 | # This is necessary if your schema can't be completely dumped by the schema dumper, 49 | # like if you have constraints or database-specific column types 50 | # config.active_record.schema_format = :sql 51 | 52 | # Enforce whitelist mode for mass assignment. 53 | # This will create an empty whitelist of attributes available for mass-assignment for all models 54 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 55 | # parameters by using an attr_accessible or attr_protected declaration. 56 | config.active_record.whitelist_attributes = true 57 | 58 | # Enable the asset pipeline 59 | config.assets.enabled = true 60 | 61 | # Version of your assets, change this if you want to expire all your assets 62 | config.assets.version = '1.0' 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /store-after/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /store-after/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /store-after/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Store::Application.initialize! 6 | -------------------------------------------------------------------------------- /store-after/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Raise exception on mass assignment protection for Active Record models 26 | config.active_record.mass_assignment_sanitizer = :strict 27 | 28 | # Log the query plan for queries taking more than this (works 29 | # with SQLite, MySQL, and PostgreSQL) 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 31 | 32 | # Do not compress assets 33 | config.assets.compress = false 34 | 35 | # Expands the lines which load the assets 36 | config.assets.debug = true 37 | end 38 | -------------------------------------------------------------------------------- /store-after/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to nil and saved in location specified by config.assets.prefix 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | # Log the query plan for queries taking more than this (works 65 | # with SQLite, MySQL, and PostgreSQL) 66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 67 | end 68 | -------------------------------------------------------------------------------- /store-after/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /store-after/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /store-after/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /store-after/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | 7 | Mime::Type.register "application/xls", :xls 8 | -------------------------------------------------------------------------------- /store-after/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Store::Application.config.secret_token = 'b833ad3a6a6e869eae95c8f7c88c4ea32979bcc47c0b866a1d78f79d8d62ecba49496e0a0442616d97952355745f72b27a69d44059e57844366105dbe380ac87' 8 | -------------------------------------------------------------------------------- /store-after/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Store::Application.config.session_store :cookie_store, key: '_store_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Store::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /store-after/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /store-after/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /store-after/config/routes.rb: -------------------------------------------------------------------------------- 1 | Store::Application.routes.draw do 2 | resources :products do 3 | collection { post :import } 4 | end 5 | root to: 'products#index' 6 | end 7 | -------------------------------------------------------------------------------- /store-after/db/migrate/20120701210336_create_products.rb: -------------------------------------------------------------------------------- 1 | class CreateProducts < ActiveRecord::Migration 2 | def change 3 | create_table :products do |t| 4 | t.string :name 5 | t.date :released_on 6 | t.decimal :price, :precision => 2, :scale => 8 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /store-after/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20120701210336) do 15 | 16 | create_table "products", :force => true do |t| 17 | t.string "name" 18 | t.date "released_on" 19 | t.decimal "price", :precision => 2, :scale => 8 20 | t.datetime "created_at", :null => false 21 | t.datetime "updated_at", :null => false 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /store-after/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | Product.create!(name: "Settlers of Catan", price: 34.95, released_on: rand(1..90).days.ago) 3 | Product.create!(name: "Red Shirt", price: 12.49, released_on: rand(1..90).days.ago) 4 | Product.create!(name: "Technodrome", price: 27.99, released_on: rand(1..90).days.ago) 5 | Product.create!(name: "Acoustic Guitar", price: 1025.00, released_on: rand(1..90).days.ago) 6 | Product.create!(name: "Agricola", price: 45.99, released_on: rand(1..90).days.ago) 7 | -------------------------------------------------------------------------------- /store-after/doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /store-after/lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/lib/assets/.gitkeep -------------------------------------------------------------------------------- /store-after/lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /store-after/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/log/.gitkeep -------------------------------------------------------------------------------- /store-after/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /store-after/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /store-after/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /store-after/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/public/favicon.ico -------------------------------------------------------------------------------- /store-after/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /store-after/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /store-after/test/fixtures/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/test/fixtures/.gitkeep -------------------------------------------------------------------------------- /store-after/test/fixtures/products.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 2 | 3 | one: 4 | name: MyString 5 | released_on: 2012-07-01 14:03:36 6 | price: 9.99 7 | 8 | two: 9 | name: MyString 10 | released_on: 2012-07-01 14:03:36 11 | price: 9.99 12 | -------------------------------------------------------------------------------- /store-after/test/functional/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/test/functional/.gitkeep -------------------------------------------------------------------------------- /store-after/test/functional/products_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductsControllerTest < ActionController::TestCase 4 | setup do 5 | @product = products(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:products) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create product" do 20 | assert_difference('Product.count') do 21 | post :create, product: { name: @product.name, price: @product.price, released_on: @product.released_on } 22 | end 23 | 24 | assert_redirected_to product_path(assigns(:product)) 25 | end 26 | 27 | test "should show product" do 28 | get :show, id: @product 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @product 34 | assert_response :success 35 | end 36 | 37 | test "should update product" do 38 | put :update, id: @product, product: { name: @product.name, price: @product.price, released_on: @product.released_on } 39 | assert_redirected_to product_path(assigns(:product)) 40 | end 41 | 42 | test "should destroy product" do 43 | assert_difference('Product.count', -1) do 44 | delete :destroy, id: @product 45 | end 46 | 47 | assert_redirected_to products_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /store-after/test/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/test/integration/.gitkeep -------------------------------------------------------------------------------- /store-after/test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'rails/performance_test_help' 3 | 4 | class BrowsingTest < ActionDispatch::PerformanceTest 5 | # Refer to the documentation for all available options 6 | # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] 7 | # :output => 'tmp/performance', :formats => [:flat] } 8 | 9 | def test_homepage 10 | get '/' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /store-after/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 7 | # 8 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 9 | # -- they do not yet inherit this setting 10 | fixtures :all 11 | 12 | # Add more helper methods to be used by all tests here... 13 | end 14 | -------------------------------------------------------------------------------- /store-after/test/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/test/unit/.gitkeep -------------------------------------------------------------------------------- /store-after/test/unit/helpers/products_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /store-after/test/unit/product_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /store-after/vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/vendor/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /store-after/vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/vendor/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /store-after/vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-after/vendor/plugins/.gitkeep -------------------------------------------------------------------------------- /store-before/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile ~/.gitignore_global 6 | 7 | # Ignore bundler config 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/*.log 15 | /tmp 16 | -------------------------------------------------------------------------------- /store-before/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rails', '3.2.9' 4 | 5 | # Bundle edge Rails instead: 6 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 7 | 8 | gem 'sqlite3' 9 | 10 | 11 | # Gems used only for assets and not required 12 | # in production environments by default. 13 | group :assets do 14 | gem 'sass-rails', '~> 3.2.3' 15 | gem 'coffee-rails', '~> 3.2.1' 16 | 17 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 18 | # gem 'therubyracer', :platforms => :ruby 19 | 20 | gem 'uglifier', '>= 1.0.3' 21 | end 22 | 23 | gem 'jquery-rails' 24 | 25 | # To use ActiveModel has_secure_password 26 | # gem 'bcrypt-ruby', '~> 3.0.0' 27 | 28 | # To use Jbuilder templates for JSON 29 | # gem 'jbuilder' 30 | 31 | # Use unicorn as the app server 32 | # gem 'unicorn' 33 | 34 | # Deploy with Capistrano 35 | # gem 'capistrano' 36 | 37 | # To use debugger 38 | # gem 'debugger' 39 | -------------------------------------------------------------------------------- /store-before/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (3.2.9) 5 | actionpack (= 3.2.9) 6 | mail (~> 2.4.4) 7 | actionpack (3.2.9) 8 | activemodel (= 3.2.9) 9 | activesupport (= 3.2.9) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | journey (~> 1.0.4) 13 | rack (~> 1.4.0) 14 | rack-cache (~> 1.2) 15 | rack-test (~> 0.6.1) 16 | sprockets (~> 2.2.1) 17 | activemodel (3.2.9) 18 | activesupport (= 3.2.9) 19 | builder (~> 3.0.0) 20 | activerecord (3.2.9) 21 | activemodel (= 3.2.9) 22 | activesupport (= 3.2.9) 23 | arel (~> 3.0.2) 24 | tzinfo (~> 0.3.29) 25 | activeresource (3.2.9) 26 | activemodel (= 3.2.9) 27 | activesupport (= 3.2.9) 28 | activesupport (3.2.9) 29 | i18n (~> 0.6) 30 | multi_json (~> 1.0) 31 | arel (3.0.2) 32 | builder (3.0.4) 33 | coffee-rails (3.2.2) 34 | coffee-script (>= 2.2.0) 35 | railties (~> 3.2.0) 36 | coffee-script (2.2.0) 37 | coffee-script-source 38 | execjs 39 | coffee-script-source (1.4.0) 40 | erubis (2.7.0) 41 | execjs (1.4.0) 42 | multi_json (~> 1.0) 43 | hike (1.2.1) 44 | i18n (0.6.1) 45 | journey (1.0.4) 46 | jquery-rails (2.1.4) 47 | railties (>= 3.0, < 5.0) 48 | thor (>= 0.14, < 2.0) 49 | json (1.7.5) 50 | mail (2.4.4) 51 | i18n (>= 0.4.0) 52 | mime-types (~> 1.16) 53 | treetop (~> 1.4.8) 54 | mime-types (1.19) 55 | multi_json (1.4.0) 56 | polyglot (0.3.3) 57 | rack (1.4.1) 58 | rack-cache (1.2) 59 | rack (>= 0.4) 60 | rack-ssl (1.3.2) 61 | rack 62 | rack-test (0.6.2) 63 | rack (>= 1.0) 64 | rails (3.2.9) 65 | actionmailer (= 3.2.9) 66 | actionpack (= 3.2.9) 67 | activerecord (= 3.2.9) 68 | activeresource (= 3.2.9) 69 | activesupport (= 3.2.9) 70 | bundler (~> 1.0) 71 | railties (= 3.2.9) 72 | railties (3.2.9) 73 | actionpack (= 3.2.9) 74 | activesupport (= 3.2.9) 75 | rack-ssl (~> 1.3.2) 76 | rake (>= 0.8.7) 77 | rdoc (~> 3.4) 78 | thor (>= 0.14.6, < 2.0) 79 | rake (10.0.2) 80 | rdoc (3.12) 81 | json (~> 1.4) 82 | sass (3.2.3) 83 | sass-rails (3.2.5) 84 | railties (~> 3.2.0) 85 | sass (>= 3.1.10) 86 | tilt (~> 1.3) 87 | sprockets (2.2.2) 88 | hike (~> 1.2) 89 | multi_json (~> 1.0) 90 | rack (~> 1.0) 91 | tilt (~> 1.1, != 1.3.0) 92 | sqlite3 (1.3.6) 93 | thor (0.16.0) 94 | tilt (1.3.3) 95 | treetop (1.4.12) 96 | polyglot 97 | polyglot (>= 0.3.1) 98 | tzinfo (0.3.35) 99 | uglifier (1.3.0) 100 | execjs (>= 0.3.0) 101 | multi_json (~> 1.0, >= 1.0.2) 102 | 103 | PLATFORMS 104 | ruby 105 | 106 | DEPENDENCIES 107 | coffee-rails (~> 3.2.1) 108 | jquery-rails 109 | rails (= 3.2.9) 110 | sass-rails (~> 3.2.3) 111 | sqlite3 112 | uglifier (>= 1.0.3) 113 | -------------------------------------------------------------------------------- /store-before/README.md: -------------------------------------------------------------------------------- 1 | # RailsCasts Example Application 2 | 3 | Run these commands to try it out. 4 | 5 | ``` 6 | bundle 7 | rake db:setup 8 | rails s 9 | ``` 10 | 11 | Requires Ruby 1.9.2 or later to run. 12 | -------------------------------------------------------------------------------- /store-before/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Store::Application.load_tasks 8 | -------------------------------------------------------------------------------- /store-before/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 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 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | -------------------------------------------------------------------------------- /store-before/app/assets/javascripts/products.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /store-before/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 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 top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /store-before/app/assets/stylesheets/layout.css.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | background-color: #4B7399; 3 | font-family: Verdana, Helvetica, Arial; 4 | font-size: 14px; 5 | } 6 | 7 | a img { 8 | border: none; 9 | } 10 | 11 | a { 12 | color: #0000FF; 13 | } 14 | 15 | .clear { 16 | clear: both; 17 | height: 0; 18 | overflow: hidden; 19 | } 20 | 21 | #container { 22 | width: 80%; 23 | margin: 0 auto; 24 | background-color: #FFF; 25 | padding: 20px 40px; 26 | border: solid 1px black; 27 | margin-top: 20px; 28 | } 29 | 30 | #flash_notice, #flash_error, #flash_alert { 31 | padding: 5px 8px; 32 | margin: 10px 0; 33 | } 34 | 35 | #flash_notice { 36 | background-color: #CFC; 37 | border: solid 1px #6C6; 38 | } 39 | 40 | #flash_error, #flash_alert { 41 | background-color: #FCC; 42 | border: solid 1px #C66; 43 | } 44 | 45 | .field_with_errors { 46 | display: inline; 47 | } 48 | 49 | .error_messages { 50 | width: 400px; 51 | border: 2px solid #CF0000; 52 | padding: 0px; 53 | padding-bottom: 12px; 54 | margin-bottom: 20px; 55 | background-color: #f0f0f0; 56 | font-size: 12px; 57 | } 58 | 59 | .error_messages h2 { 60 | text-align: left; 61 | font-weight: bold; 62 | padding: 5px 10px; 63 | font-size: 12px; 64 | margin: 0; 65 | background-color: #c00; 66 | color: #fff; 67 | } 68 | 69 | .error_messages p { 70 | margin: 8px 10px; 71 | } 72 | 73 | .error_messages ul { 74 | margin-bottom: 0; 75 | } 76 | 77 | form .field, form .actions { 78 | margin: 12px 0; 79 | } 80 | -------------------------------------------------------------------------------- /store-before/app/assets/stylesheets/products.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the products controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | table td, table th { 5 | padding-right: 20px; 6 | padding-bottom: 5px; 7 | text-align: left; 8 | &:last-child { 9 | text-align: right; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /store-before/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /store-before/app/controllers/products_controller.rb: -------------------------------------------------------------------------------- 1 | class ProductsController < ApplicationController 2 | def index 3 | @products = Product.order(:name) 4 | respond_to do |format| 5 | format.html 6 | format.csv { send_data @products.to_csv } 7 | format.xls # { send_data @products.to_csv(col_sep: "\t") } 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /store-before/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /store-before/app/helpers/products_helper.rb: -------------------------------------------------------------------------------- 1 | module ProductsHelper 2 | end 3 | -------------------------------------------------------------------------------- /store-before/app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/app/mailers/.gitkeep -------------------------------------------------------------------------------- /store-before/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/app/models/.gitkeep -------------------------------------------------------------------------------- /store-before/app/models/product.rb: -------------------------------------------------------------------------------- 1 | class Product < ActiveRecord::Base 2 | attr_accessible :name, :price, :released_on 3 | 4 | def self.to_csv(options = {}) 5 | CSV.generate(options) do |csv| 6 | csv << column_names 7 | all.each do |product| 8 | csv << product.attributes.values_at(*column_names) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /store-before/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Products 5 | <%= stylesheet_link_tag "application", media: "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tag %> 8 | 9 | 10 |
11 | <% flash.each do |name, msg| %> 12 | <%= content_tag :div, msg, id: "flash_#{name}" %> 13 | <% end %> 14 | <%= yield %> 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /store-before/app/views/products/index.html.erb: -------------------------------------------------------------------------------- 1 |

Products

2 | 3 |

4 | Download: 5 | <%= link_to "CSV", products_path(format: "csv") %> | 6 | <%= link_to "Excel", products_path(format: "xls") %> 7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <% @products.each do |product| %> 16 | 17 | 18 | 19 | 20 | 21 | <% end %> 22 |
Product NameRelease DatePrice
<%= product.name %><%= product.released_on.strftime("%B %e, %Y") %><%= number_to_currency(product.price) %>
23 | -------------------------------------------------------------------------------- /store-before/app/views/products/index.xls.erb: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | ID 11 | Name 12 | Release Date 13 | Price 14 | 15 | <% @products.each do |product| %> 16 | 17 | <%= product.id %> 18 | <%= product.name %> 19 | <%= product.released_on %> 20 | <%= product.price %> 21 | 22 | <% end %> 23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /store-before/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Store::Application 5 | -------------------------------------------------------------------------------- /store-before/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'csv' 4 | require 'rails/all' 5 | 6 | if defined?(Bundler) 7 | # If you precompile assets before deploying to production, use this line 8 | Bundler.require(*Rails.groups(:assets => %w(development test))) 9 | # If you want your assets lazily compiled in production, use this line 10 | # Bundler.require(:default, :assets, Rails.env) 11 | end 12 | 13 | module Store 14 | class Application < Rails::Application 15 | # Settings in config/environments/* take precedence over those specified here. 16 | # Application configuration should go into files in config/initializers 17 | # -- all .rb files in that directory are automatically loaded. 18 | 19 | # Custom directories with classes and modules you want to be autoloadable. 20 | # config.autoload_paths += %W(#{config.root}/extras) 21 | 22 | # Only load the plugins named here, in the order given (default is alphabetical). 23 | # :all can be used as a placeholder for all plugins not explicitly named. 24 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 25 | 26 | # Activate observers that should always be running. 27 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 28 | 29 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 30 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 31 | # config.time_zone = 'Central Time (US & Canada)' 32 | 33 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 34 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 35 | # config.i18n.default_locale = :de 36 | 37 | # Configure the default encoding used in templates for Ruby 1.9. 38 | config.encoding = "utf-8" 39 | 40 | # Configure sensitive parameters which will be filtered from the log file. 41 | config.filter_parameters += [:password] 42 | 43 | # Enable escaping HTML in JSON. 44 | config.active_support.escape_html_entities_in_json = true 45 | 46 | # Use SQL instead of Active Record's schema dumper when creating the database. 47 | # This is necessary if your schema can't be completely dumped by the schema dumper, 48 | # like if you have constraints or database-specific column types 49 | # config.active_record.schema_format = :sql 50 | 51 | # Enforce whitelist mode for mass assignment. 52 | # This will create an empty whitelist of attributes available for mass-assignment for all models 53 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 54 | # parameters by using an attr_accessible or attr_protected declaration. 55 | config.active_record.whitelist_attributes = true 56 | 57 | # Enable the asset pipeline 58 | config.assets.enabled = true 59 | 60 | # Version of your assets, change this if you want to expire all your assets 61 | config.assets.version = '1.0' 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /store-before/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /store-before/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /store-before/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Store::Application.initialize! 6 | -------------------------------------------------------------------------------- /store-before/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Raise exception on mass assignment protection for Active Record models 26 | config.active_record.mass_assignment_sanitizer = :strict 27 | 28 | # Log the query plan for queries taking more than this (works 29 | # with SQLite, MySQL, and PostgreSQL) 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 31 | 32 | # Do not compress assets 33 | config.assets.compress = false 34 | 35 | # Expands the lines which load the assets 36 | config.assets.debug = true 37 | end 38 | -------------------------------------------------------------------------------- /store-before/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to nil and saved in location specified by config.assets.prefix 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | # Log the query plan for queries taking more than this (works 65 | # with SQLite, MySQL, and PostgreSQL) 66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 67 | end 68 | -------------------------------------------------------------------------------- /store-before/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /store-before/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /store-before/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /store-before/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | 7 | Mime::Type.register "application/xls", :xls 8 | -------------------------------------------------------------------------------- /store-before/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Store::Application.config.secret_token = 'b833ad3a6a6e869eae95c8f7c88c4ea32979bcc47c0b866a1d78f79d8d62ecba49496e0a0442616d97952355745f72b27a69d44059e57844366105dbe380ac87' 8 | -------------------------------------------------------------------------------- /store-before/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Store::Application.config.session_store :cookie_store, key: '_store_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Store::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /store-before/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /store-before/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /store-before/config/routes.rb: -------------------------------------------------------------------------------- 1 | Store::Application.routes.draw do 2 | resources :products 3 | root to: 'products#index' 4 | end 5 | -------------------------------------------------------------------------------- /store-before/db/migrate/20120701210336_create_products.rb: -------------------------------------------------------------------------------- 1 | class CreateProducts < ActiveRecord::Migration 2 | def change 3 | create_table :products do |t| 4 | t.string :name 5 | t.date :released_on 6 | t.decimal :price, :precision => 2, :scale => 8 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /store-before/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20120701210336) do 15 | 16 | create_table "products", :force => true do |t| 17 | t.string "name" 18 | t.date "released_on" 19 | t.decimal "price", :precision => 2, :scale => 8 20 | t.datetime "created_at", :null => false 21 | t.datetime "updated_at", :null => false 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /store-before/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | Product.create!(name: "Settlers of Catan", price: 34.95, released_on: rand(1..90).days.ago) 3 | Product.create!(name: "Red Shirt", price: 12.49, released_on: rand(1..90).days.ago) 4 | Product.create!(name: "Technodrome", price: 27.99, released_on: rand(1..90).days.ago) 5 | Product.create!(name: "Acoustic Guitar", price: 1025.00, released_on: rand(1..90).days.ago) 6 | Product.create!(name: "Agricola", price: 45.99, released_on: rand(1..90).days.ago) 7 | -------------------------------------------------------------------------------- /store-before/doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /store-before/lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/lib/assets/.gitkeep -------------------------------------------------------------------------------- /store-before/lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /store-before/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/log/.gitkeep -------------------------------------------------------------------------------- /store-before/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /store-before/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /store-before/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /store-before/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/public/favicon.ico -------------------------------------------------------------------------------- /store-before/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /store-before/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /store-before/test/fixtures/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/test/fixtures/.gitkeep -------------------------------------------------------------------------------- /store-before/test/fixtures/products.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 2 | 3 | one: 4 | name: MyString 5 | released_on: 2012-07-01 14:03:36 6 | price: 9.99 7 | 8 | two: 9 | name: MyString 10 | released_on: 2012-07-01 14:03:36 11 | price: 9.99 12 | -------------------------------------------------------------------------------- /store-before/test/functional/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/test/functional/.gitkeep -------------------------------------------------------------------------------- /store-before/test/functional/products_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductsControllerTest < ActionController::TestCase 4 | setup do 5 | @product = products(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:products) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create product" do 20 | assert_difference('Product.count') do 21 | post :create, product: { name: @product.name, price: @product.price, released_on: @product.released_on } 22 | end 23 | 24 | assert_redirected_to product_path(assigns(:product)) 25 | end 26 | 27 | test "should show product" do 28 | get :show, id: @product 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @product 34 | assert_response :success 35 | end 36 | 37 | test "should update product" do 38 | put :update, id: @product, product: { name: @product.name, price: @product.price, released_on: @product.released_on } 39 | assert_redirected_to product_path(assigns(:product)) 40 | end 41 | 42 | test "should destroy product" do 43 | assert_difference('Product.count', -1) do 44 | delete :destroy, id: @product 45 | end 46 | 47 | assert_redirected_to products_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /store-before/test/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/test/integration/.gitkeep -------------------------------------------------------------------------------- /store-before/test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'rails/performance_test_help' 3 | 4 | class BrowsingTest < ActionDispatch::PerformanceTest 5 | # Refer to the documentation for all available options 6 | # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] 7 | # :output => 'tmp/performance', :formats => [:flat] } 8 | 9 | def test_homepage 10 | get '/' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /store-before/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 7 | # 8 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 9 | # -- they do not yet inherit this setting 10 | fixtures :all 11 | 12 | # Add more helper methods to be used by all tests here... 13 | end 14 | -------------------------------------------------------------------------------- /store-before/test/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/test/unit/.gitkeep -------------------------------------------------------------------------------- /store-before/test/unit/helpers/products_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /store-before/test/unit/product_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /store-before/vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/vendor/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /store-before/vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/vendor/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /store-before/vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-before/vendor/plugins/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile ~/.gitignore_global 6 | 7 | # Ignore bundler config 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/*.log 15 | /tmp 16 | -------------------------------------------------------------------------------- /store-with-validations/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rails', '3.2.9' 4 | 5 | # Bundle edge Rails instead: 6 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 7 | 8 | gem 'sqlite3' 9 | 10 | 11 | # Gems used only for assets and not required 12 | # in production environments by default. 13 | group :assets do 14 | gem 'sass-rails', '~> 3.2.3' 15 | gem 'coffee-rails', '~> 3.2.1' 16 | 17 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 18 | # gem 'therubyracer', :platforms => :ruby 19 | 20 | gem 'uglifier', '>= 1.0.3' 21 | end 22 | 23 | gem 'jquery-rails' 24 | 25 | # To use ActiveModel has_secure_password 26 | # gem 'bcrypt-ruby', '~> 3.0.0' 27 | 28 | # To use Jbuilder templates for JSON 29 | # gem 'jbuilder' 30 | 31 | # Use unicorn as the app server 32 | # gem 'unicorn' 33 | 34 | # Deploy with Capistrano 35 | # gem 'capistrano' 36 | 37 | # To use debugger 38 | # gem 'debugger' 39 | 40 | gem 'roo' 41 | -------------------------------------------------------------------------------- /store-with-validations/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (3.2.9) 5 | actionpack (= 3.2.9) 6 | mail (~> 2.4.4) 7 | actionpack (3.2.9) 8 | activemodel (= 3.2.9) 9 | activesupport (= 3.2.9) 10 | builder (~> 3.0.0) 11 | erubis (~> 2.7.0) 12 | journey (~> 1.0.4) 13 | rack (~> 1.4.0) 14 | rack-cache (~> 1.2) 15 | rack-test (~> 0.6.1) 16 | sprockets (~> 2.2.1) 17 | activemodel (3.2.9) 18 | activesupport (= 3.2.9) 19 | builder (~> 3.0.0) 20 | activerecord (3.2.9) 21 | activemodel (= 3.2.9) 22 | activesupport (= 3.2.9) 23 | arel (~> 3.0.2) 24 | tzinfo (~> 0.3.29) 25 | activeresource (3.2.9) 26 | activemodel (= 3.2.9) 27 | activesupport (= 3.2.9) 28 | activesupport (3.2.9) 29 | i18n (~> 0.6) 30 | multi_json (~> 1.0) 31 | arel (3.0.2) 32 | builder (3.0.4) 33 | choice (0.1.6) 34 | coffee-rails (3.2.2) 35 | coffee-script (>= 2.2.0) 36 | railties (~> 3.2.0) 37 | coffee-script (2.2.0) 38 | coffee-script-source 39 | execjs 40 | coffee-script-source (1.4.0) 41 | erubis (2.7.0) 42 | execjs (1.4.0) 43 | multi_json (~> 1.0) 44 | faraday (0.8.4) 45 | multipart-post (~> 1.1) 46 | google-spreadsheet-ruby (0.3.0) 47 | google_drive (>= 0.3.0) 48 | google_drive (0.3.2) 49 | nokogiri (>= 1.4.4, != 1.5.2, != 1.5.1) 50 | oauth (>= 0.3.6) 51 | oauth2 (>= 0.5.0) 52 | hike (1.2.1) 53 | httpauth (0.2.0) 54 | i18n (0.6.1) 55 | journey (1.0.4) 56 | jquery-rails (2.1.4) 57 | railties (>= 3.0, < 5.0) 58 | thor (>= 0.14, < 2.0) 59 | json (1.7.5) 60 | jwt (0.1.5) 61 | multi_json (>= 1.0) 62 | log4r (1.1.10) 63 | mail (2.4.4) 64 | i18n (>= 0.4.0) 65 | mime-types (~> 1.16) 66 | treetop (~> 1.4.8) 67 | mime-types (1.19) 68 | multi_json (1.4.0) 69 | multipart-post (1.1.5) 70 | nokogiri (1.5.5) 71 | oauth (0.4.7) 72 | oauth2 (0.8.0) 73 | faraday (~> 0.8) 74 | httpauth (~> 0.1) 75 | jwt (~> 0.1.4) 76 | multi_json (~> 1.0) 77 | rack (~> 1.2) 78 | polyglot (0.3.3) 79 | rack (1.4.1) 80 | rack-cache (1.2) 81 | rack (>= 0.4) 82 | rack-ssl (1.3.2) 83 | rack 84 | rack-test (0.6.2) 85 | rack (>= 1.0) 86 | rails (3.2.9) 87 | actionmailer (= 3.2.9) 88 | actionpack (= 3.2.9) 89 | activerecord (= 3.2.9) 90 | activeresource (= 3.2.9) 91 | activesupport (= 3.2.9) 92 | bundler (~> 1.0) 93 | railties (= 3.2.9) 94 | railties (3.2.9) 95 | actionpack (= 3.2.9) 96 | activesupport (= 3.2.9) 97 | rack-ssl (~> 1.3.2) 98 | rake (>= 0.8.7) 99 | rdoc (~> 3.4) 100 | thor (>= 0.14.6, < 2.0) 101 | rake (10.0.2) 102 | rdoc (3.12) 103 | json (~> 1.4) 104 | roo (1.10.1) 105 | choice (>= 0.1.4) 106 | google-spreadsheet-ruby (>= 0.1.5) 107 | nokogiri (>= 1.5.0) 108 | rubyzip (>= 0.9.4) 109 | spreadsheet (> 0.6.4) 110 | todonotes (>= 0.1.0) 111 | ruby-ole (1.2.11.5) 112 | rubyzip (0.9.9) 113 | sass (3.2.3) 114 | sass-rails (3.2.5) 115 | railties (~> 3.2.0) 116 | sass (>= 3.1.10) 117 | tilt (~> 1.3) 118 | spreadsheet (0.7.5) 119 | ruby-ole (>= 1.0) 120 | sprockets (2.2.2) 121 | hike (~> 1.2) 122 | multi_json (~> 1.0) 123 | rack (~> 1.0) 124 | tilt (~> 1.1, != 1.3.0) 125 | sqlite3 (1.3.6) 126 | thor (0.16.0) 127 | tilt (1.3.3) 128 | todonotes (0.1.1) 129 | log4r 130 | treetop (1.4.12) 131 | polyglot 132 | polyglot (>= 0.3.1) 133 | tzinfo (0.3.35) 134 | uglifier (1.3.0) 135 | execjs (>= 0.3.0) 136 | multi_json (~> 1.0, >= 1.0.2) 137 | 138 | PLATFORMS 139 | ruby 140 | 141 | DEPENDENCIES 142 | coffee-rails (~> 3.2.1) 143 | jquery-rails 144 | rails (= 3.2.9) 145 | roo 146 | sass-rails (~> 3.2.3) 147 | sqlite3 148 | uglifier (>= 1.0.3) 149 | -------------------------------------------------------------------------------- /store-with-validations/README.md: -------------------------------------------------------------------------------- 1 | # RailsCasts Example Application 2 | 3 | Run these commands to try it out. 4 | 5 | ``` 6 | bundle 7 | rake db:setup 8 | rails s 9 | ``` 10 | 11 | Requires Ruby 1.9.2 or later to run. 12 | -------------------------------------------------------------------------------- /store-with-validations/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Store::Application.load_tasks 8 | -------------------------------------------------------------------------------- /store-with-validations/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 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 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require_tree . 16 | -------------------------------------------------------------------------------- /store-with-validations/app/assets/javascripts/product_imports.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /store-with-validations/app/assets/javascripts/products.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /store-with-validations/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 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 top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require_tree . 13 | */ 14 | -------------------------------------------------------------------------------- /store-with-validations/app/assets/stylesheets/layout.css.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | background-color: #4B7399; 3 | font-family: Verdana, Helvetica, Arial; 4 | font-size: 14px; 5 | } 6 | 7 | a { 8 | color: #0000FF; 9 | img { border: none; } 10 | } 11 | 12 | .clear { 13 | clear: both; 14 | height: 0; 15 | overflow: hidden; 16 | } 17 | 18 | #container { 19 | width: 80%; 20 | margin: 0 auto; 21 | background-color: #FFF; 22 | padding: 20px 40px; 23 | border: solid 1px black; 24 | margin-top: 20px; 25 | } 26 | 27 | #flash_notice { 28 | color: #00B205; 29 | } 30 | 31 | #flash_alert { 32 | color: #D00; 33 | } 34 | 35 | .error_messages, #error_explanation { 36 | width: 400px; 37 | border: 2px solid #CF0000; 38 | padding: 0px; 39 | padding-bottom: 12px; 40 | margin-bottom: 20px; 41 | background-color: #f0f0f0; 42 | font-size: 12px; 43 | 44 | h2 { 45 | text-align: left; 46 | font-weight: bold; 47 | padding: 5px 10px; 48 | font-size: 12px; 49 | margin: 0; 50 | background-color: #c00; 51 | color: #fff; 52 | } 53 | 54 | p { margin: 8px 10px; } 55 | ul { margin-bottom: 0; } 56 | } 57 | 58 | .field_with_errors { 59 | display: inline; 60 | } 61 | 62 | form .field, form .actions { 63 | margin: 12px 0; 64 | } 65 | -------------------------------------------------------------------------------- /store-with-validations/app/assets/stylesheets/product_imports.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the product_imports controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /store-with-validations/app/assets/stylesheets/products.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the products controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | table td, table th { 5 | padding-right: 20px; 6 | padding-bottom: 5px; 7 | text-align: left; 8 | &:last-child { 9 | text-align: right; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /store-with-validations/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /store-with-validations/app/controllers/product_imports_controller.rb: -------------------------------------------------------------------------------- 1 | class ProductImportsController < ApplicationController 2 | def new 3 | @product_import = ProductImport.new 4 | end 5 | 6 | def create 7 | @product_import = ProductImport.new(params[:product_import]) 8 | if @product_import.save 9 | redirect_to root_url, notice: "Imported products successfully." 10 | else 11 | render :new 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /store-with-validations/app/controllers/products_controller.rb: -------------------------------------------------------------------------------- 1 | class ProductsController < ApplicationController 2 | def index 3 | @products = Product.order(:name) 4 | respond_to do |format| 5 | format.html 6 | format.csv { send_data @products.to_csv } 7 | format.xls # { send_data @products.to_csv(col_sep: "\t") } 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /store-with-validations/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /store-with-validations/app/helpers/product_imports_helper.rb: -------------------------------------------------------------------------------- 1 | module ProductImportsHelper 2 | end 3 | -------------------------------------------------------------------------------- /store-with-validations/app/helpers/products_helper.rb: -------------------------------------------------------------------------------- 1 | module ProductsHelper 2 | end 3 | -------------------------------------------------------------------------------- /store-with-validations/app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/app/mailers/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/app/models/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/app/models/product.rb: -------------------------------------------------------------------------------- 1 | class Product < ActiveRecord::Base 2 | attr_accessible :name, :price, :released_on 3 | 4 | validates_presence_of :price 5 | 6 | def self.to_csv(options = {}) 7 | CSV.generate(options) do |csv| 8 | csv << column_names 9 | all.each do |product| 10 | csv << product.attributes.values_at(*column_names) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /store-with-validations/app/models/product_import.rb: -------------------------------------------------------------------------------- 1 | class ProductImport 2 | # switch to ActiveModel::Model in Rails 4 3 | extend ActiveModel::Naming 4 | include ActiveModel::Conversion 5 | include ActiveModel::Validations 6 | 7 | attr_accessor :file 8 | 9 | def initialize(attributes = {}) 10 | attributes.each { |name, value| send("#{name}=", value) } 11 | end 12 | 13 | def persisted? 14 | false 15 | end 16 | 17 | def save 18 | if imported_products.map(&:valid?).all? 19 | imported_products.each(&:save!) 20 | true 21 | else 22 | imported_products.each_with_index do |product, index| 23 | product.errors.full_messages.each do |message| 24 | errors.add :base, "Row #{index+2}: #{message}" 25 | end 26 | end 27 | false 28 | end 29 | end 30 | 31 | def imported_products 32 | @imported_products ||= load_imported_products 33 | end 34 | 35 | def load_imported_products 36 | spreadsheet = open_spreadsheet 37 | header = spreadsheet.row(1) 38 | (2..spreadsheet.last_row).map do |i| 39 | row = Hash[[header, spreadsheet.row(i)].transpose] 40 | product = Product.find_by_id(row["id"]) || Product.new 41 | product.attributes = row.to_hash.slice(*Product.accessible_attributes) 42 | product 43 | end 44 | end 45 | 46 | def open_spreadsheet 47 | case File.extname(file.original_filename) 48 | when ".csv" then Csv.new(file.path, nil, :ignore) 49 | when ".xls" then Excel.new(file.path, nil, :ignore) 50 | when ".xlsx" then Excelx.new(file.path, nil, :ignore) 51 | else raise "Unknown file type: #{file.original_filename}" 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /store-with-validations/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Products 5 | <%= stylesheet_link_tag "application", media: "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tag %> 8 | 9 | 10 |
11 | <% flash.each do |name, msg| %> 12 | <%= content_tag :div, msg, id: "flash_#{name}" %> 13 | <% end %> 14 | <%= yield %> 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /store-with-validations/app/views/product_imports/new.html.erb: -------------------------------------------------------------------------------- 1 |

Product Import

2 | 3 |

A CSV or Excel file can be used to import records. The first row should be the column name. The following columns are allowed.

4 | 5 | 15 | 16 |

If an id is supplied it will update the matching record instead of creating a new one.

17 | 18 | <%= form_for @product_import do |f| %> 19 | <% if @product_import.errors.any? %> 20 |
21 |

<%= pluralize(@product_import.errors.count, "error") %> prohibited this import from completing:

22 | 27 |
28 | <% end %> 29 | 30 |
31 | <%= f.file_field :file %> 32 |
33 |
<%= f.submit "Import" %>
34 | <% end %> 35 | -------------------------------------------------------------------------------- /store-with-validations/app/views/products/index.html.erb: -------------------------------------------------------------------------------- 1 |

Products

2 | 3 |

4 | Download: 5 | <%= link_to "CSV", products_path(format: "csv") %> | 6 | <%= link_to "Excel", products_path(format: "xls") %> 7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | <% @products.each do |product| %> 16 | 17 | 18 | 19 | 20 | 21 | <% end %> 22 |
Product NameRelease DatePrice
<%= product.name %><%= product.released_on.strftime("%B %e, %Y") %><%= number_to_currency(product.price) %>
23 | 24 |

<%= link_to "Import products", new_product_import_path %>

25 | -------------------------------------------------------------------------------- /store-with-validations/app/views/products/index.xls.erb: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | ID 11 | Name 12 | Release Date 13 | Price 14 | 15 | <% @products.each do |product| %> 16 | 17 | <%= product.id %> 18 | <%= product.name %> 19 | <%= product.released_on %> 20 | <%= product.price %> 21 | 22 | <% end %> 23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /store-with-validations/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Store::Application 5 | -------------------------------------------------------------------------------- /store-with-validations/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'csv' 4 | require 'iconv' 5 | require 'rails/all' 6 | 7 | if defined?(Bundler) 8 | # If you precompile assets before deploying to production, use this line 9 | Bundler.require(*Rails.groups(:assets => %w(development test))) 10 | # If you want your assets lazily compiled in production, use this line 11 | # Bundler.require(:default, :assets, Rails.env) 12 | end 13 | 14 | module Store 15 | class Application < Rails::Application 16 | # Settings in config/environments/* take precedence over those specified here. 17 | # Application configuration should go into files in config/initializers 18 | # -- all .rb files in that directory are automatically loaded. 19 | 20 | # Custom directories with classes and modules you want to be autoloadable. 21 | # config.autoload_paths += %W(#{config.root}/extras) 22 | 23 | # Only load the plugins named here, in the order given (default is alphabetical). 24 | # :all can be used as a placeholder for all plugins not explicitly named. 25 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 26 | 27 | # Activate observers that should always be running. 28 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 29 | 30 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 31 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 32 | # config.time_zone = 'Central Time (US & Canada)' 33 | 34 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 35 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 36 | # config.i18n.default_locale = :de 37 | 38 | # Configure the default encoding used in templates for Ruby 1.9. 39 | config.encoding = "utf-8" 40 | 41 | # Configure sensitive parameters which will be filtered from the log file. 42 | config.filter_parameters += [:password] 43 | 44 | # Enable escaping HTML in JSON. 45 | config.active_support.escape_html_entities_in_json = true 46 | 47 | # Use SQL instead of Active Record's schema dumper when creating the database. 48 | # This is necessary if your schema can't be completely dumped by the schema dumper, 49 | # like if you have constraints or database-specific column types 50 | # config.active_record.schema_format = :sql 51 | 52 | # Enforce whitelist mode for mass assignment. 53 | # This will create an empty whitelist of attributes available for mass-assignment for all models 54 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 55 | # parameters by using an attr_accessible or attr_protected declaration. 56 | config.active_record.whitelist_attributes = true 57 | 58 | # Enable the asset pipeline 59 | config.assets.enabled = true 60 | 61 | # Version of your assets, change this if you want to expire all your assets 62 | config.assets.version = '1.0' 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /store-with-validations/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /store-with-validations/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /store-with-validations/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Store::Application.initialize! 6 | -------------------------------------------------------------------------------- /store-with-validations/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Raise exception on mass assignment protection for Active Record models 26 | config.active_record.mass_assignment_sanitizer = :strict 27 | 28 | # Log the query plan for queries taking more than this (works 29 | # with SQLite, MySQL, and PostgreSQL) 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 31 | 32 | # Do not compress assets 33 | config.assets.compress = false 34 | 35 | # Expands the lines which load the assets 36 | config.assets.debug = true 37 | end 38 | -------------------------------------------------------------------------------- /store-with-validations/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to nil and saved in location specified by config.assets.prefix 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | # Log the query plan for queries taking more than this (works 65 | # with SQLite, MySQL, and PostgreSQL) 66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 67 | end 68 | -------------------------------------------------------------------------------- /store-with-validations/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Store::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /store-with-validations/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /store-with-validations/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /store-with-validations/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | 7 | Mime::Type.register "application/xls", :xls 8 | -------------------------------------------------------------------------------- /store-with-validations/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Store::Application.config.secret_token = 'b833ad3a6a6e869eae95c8f7c88c4ea32979bcc47c0b866a1d78f79d8d62ecba49496e0a0442616d97952355745f72b27a69d44059e57844366105dbe380ac87' 8 | -------------------------------------------------------------------------------- /store-with-validations/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Store::Application.config.session_store :cookie_store, key: '_store_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Store::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /store-with-validations/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /store-with-validations/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /store-with-validations/config/routes.rb: -------------------------------------------------------------------------------- 1 | Store::Application.routes.draw do 2 | resources :products 3 | resources :product_imports 4 | root to: 'products#index' 5 | end 6 | -------------------------------------------------------------------------------- /store-with-validations/db/migrate/20120701210336_create_products.rb: -------------------------------------------------------------------------------- 1 | class CreateProducts < ActiveRecord::Migration 2 | def change 3 | create_table :products do |t| 4 | t.string :name 5 | t.date :released_on 6 | t.decimal :price, :precision => 2, :scale => 8 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /store-with-validations/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20120701210336) do 15 | 16 | create_table "products", :force => true do |t| 17 | t.string "name" 18 | t.date "released_on" 19 | t.decimal "price", :precision => 2, :scale => 8 20 | t.datetime "created_at", :null => false 21 | t.datetime "updated_at", :null => false 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /store-with-validations/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | Product.create!(name: "Settlers of Catan", price: 34.95, released_on: rand(1..90).days.ago) 3 | Product.create!(name: "Red Shirt", price: 12.49, released_on: rand(1..90).days.ago) 4 | Product.create!(name: "Technodrome", price: 27.99, released_on: rand(1..90).days.ago) 5 | Product.create!(name: "Acoustic Guitar", price: 1025.00, released_on: rand(1..90).days.ago) 6 | Product.create!(name: "Agricola", price: 45.99, released_on: rand(1..90).days.ago) 7 | -------------------------------------------------------------------------------- /store-with-validations/doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /store-with-validations/lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/lib/assets/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/log/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /store-with-validations/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /store-with-validations/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /store-with-validations/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/public/favicon.ico -------------------------------------------------------------------------------- /store-with-validations/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /store-with-validations/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /store-with-validations/test/fixtures/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/test/fixtures/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/test/fixtures/products.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 2 | 3 | one: 4 | name: MyString 5 | released_on: 2012-07-01 14:03:36 6 | price: 9.99 7 | 8 | two: 9 | name: MyString 10 | released_on: 2012-07-01 14:03:36 11 | price: 9.99 12 | -------------------------------------------------------------------------------- /store-with-validations/test/functional/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/test/functional/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/test/functional/product_imports_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductImportsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /store-with-validations/test/functional/products_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductsControllerTest < ActionController::TestCase 4 | setup do 5 | @product = products(:one) 6 | end 7 | 8 | test "should get index" do 9 | get :index 10 | assert_response :success 11 | assert_not_nil assigns(:products) 12 | end 13 | 14 | test "should get new" do 15 | get :new 16 | assert_response :success 17 | end 18 | 19 | test "should create product" do 20 | assert_difference('Product.count') do 21 | post :create, product: { name: @product.name, price: @product.price, released_on: @product.released_on } 22 | end 23 | 24 | assert_redirected_to product_path(assigns(:product)) 25 | end 26 | 27 | test "should show product" do 28 | get :show, id: @product 29 | assert_response :success 30 | end 31 | 32 | test "should get edit" do 33 | get :edit, id: @product 34 | assert_response :success 35 | end 36 | 37 | test "should update product" do 38 | put :update, id: @product, product: { name: @product.name, price: @product.price, released_on: @product.released_on } 39 | assert_redirected_to product_path(assigns(:product)) 40 | end 41 | 42 | test "should destroy product" do 43 | assert_difference('Product.count', -1) do 44 | delete :destroy, id: @product 45 | end 46 | 47 | assert_redirected_to products_path 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /store-with-validations/test/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/test/integration/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'rails/performance_test_help' 3 | 4 | class BrowsingTest < ActionDispatch::PerformanceTest 5 | # Refer to the documentation for all available options 6 | # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] 7 | # :output => 'tmp/performance', :formats => [:flat] } 8 | 9 | def test_homepage 10 | get '/' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /store-with-validations/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 7 | # 8 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 9 | # -- they do not yet inherit this setting 10 | fixtures :all 11 | 12 | # Add more helper methods to be used by all tests here... 13 | end 14 | -------------------------------------------------------------------------------- /store-with-validations/test/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/test/unit/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/test/unit/helpers/product_imports_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductImportsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /store-with-validations/test/unit/helpers/products_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /store-with-validations/test/unit/product_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProductTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /store-with-validations/vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/vendor/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/vendor/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /store-with-validations/vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railscasts/396-importing-csv-and-excel/4d42f7b936f15e873ffab2d176890d8efdf299c7/store-with-validations/vendor/plugins/.gitkeep --------------------------------------------------------------------------------