From 5e5985614aa589049ab45cf014da5741a1d05614 Mon Sep 17 00:00:00 2001 From: Andy Waite Date: Sun, 1 Apr 2012 17:50:15 +0100 Subject: [PATCH] Initial import --- Capfile | 11 + Gemfile | 53 ++++ README.rdoc | 261 ++++++++++++++++++ Rakefile | 7 + app/assets/images/cs.jpg | Bin 0 -> 15093 bytes app/assets/images/logo.png | Bin 0 -> 1040 bytes app/assets/images/rails.png | Bin 0 -> 1787 bytes app/assets/images/rtp.jpg | Bin 0 -> 9882 bytes app/assets/images/ruby.jpg | Bin 0 -> 8300 bytes app/assets/javascripts/admin.js.coffee | 3 + app/assets/javascripts/application.js | 25 ++ app/assets/javascripts/carts.js.coffee | 3 + app/assets/javascripts/line_items.js.coffee | 3 + app/assets/javascripts/orders.js.coffee | 3 + app/assets/javascripts/products.js.coffee | 3 + app/assets/javascripts/sessions.js.coffee | 3 + app/assets/javascripts/store.js.coffee | 9 + app/assets/javascripts/users.js.coffee | 3 + app/assets/stylesheets/admin.css.scss | 3 + app/assets/stylesheets/application.css.scss | 135 +++++++++ app/assets/stylesheets/carts.css.scss | 20 ++ app/assets/stylesheets/line_items.css.scss | 3 + app/assets/stylesheets/orders.css.scss | 3 + app/assets/stylesheets/products.css.scss | 53 ++++ app/assets/stylesheets/scaffolds.css.scss | 56 ++++ app/assets/stylesheets/sessions.css.scss | 3 + app/assets/stylesheets/store.css.scss | 57 ++++ app/assets/stylesheets/users.css.scss | 3 + app/controllers/admin_controller.rb | 13 + app/controllers/application_controller.rb | 57 ++++ app/controllers/carts_controller.rb | 99 +++++++ app/controllers/line_items_controller.rb | 106 +++++++ app/controllers/orders_controller.rb | 108 ++++++++ app/controllers/products_controller.rb | 107 +++++++ app/controllers/sessions_controller.rb | 28 ++ app/controllers/store_controller.rb | 23 ++ app/controllers/users_controller.rb | 101 +++++++ app/helpers/admin_helper.rb | 10 + app/helpers/application_helper.rb | 16 ++ app/helpers/carts_helper.rb | 10 + app/helpers/line_items_helper.rb | 10 + app/helpers/orders_helper.rb | 10 + app/helpers/products_helper.rb | 10 + app/helpers/sessions_helper.rb | 10 + app/helpers/store_helper.rb | 10 + app/helpers/users_helper.rb | 10 + app/mailers/.gitkeep | 0 app/mailers/order_notifier.rb | 33 +++ app/models/.gitkeep | 0 app/models/cart.rb | 26 ++ app/models/line_item.rb | 17 ++ app/models/order.rb | 21 ++ app/models/product.rb | 42 +++ app/models/user.rb | 21 ++ app/store.rb | 33 +++ app/views/admin/index.html.erb | 4 + app/views/carts/_cart.html.erb | 20 ++ app/views/carts/_form.html.erb | 17 ++ app/views/carts/edit.html.erb | 6 + app/views/carts/index.html.erb | 21 ++ app/views/carts/new.html.erb | 5 + app/views/carts/show.html.erb | 7 + app/views/layouts/application.html.erb | 58 ++++ app/views/line_items/_form.html.erb | 25 ++ app/views/line_items/_line_item.html.erb | 9 + app/views/line_items/_line_item.text.erb | 3 + app/views/line_items/create.js.erb | 10 + app/views/line_items/edit.html.erb | 6 + app/views/line_items/index.html.erb | 25 ++ app/views/line_items/new.html.erb | 5 + app/views/line_items/show.html.erb | 15 + app/views/order_notifier/received.text.erb | 9 + app/views/order_notifier/shipped.html.erb | 9 + app/views/order_notifier/shipped.text.erb | 3 + app/views/orders/_form.html.erb | 49 ++++ app/views/orders/edit.html.erb | 6 + app/views/orders/index.html.erb | 33 +++ app/views/orders/new.html.erb | 8 + app/views/orders/show.html.erb | 25 ++ app/views/products/_form.html.erb | 36 +++ app/views/products/edit.html.erb | 6 + app/views/products/index.html.erb | 32 +++ app/views/products/index.xml.builder | 11 + app/views/products/new.html.erb | 5 + app/views/products/show.html.erb | 25 ++ app/views/products/who_bought.atom.builder | 41 +++ app/views/products/who_bought.html.erb | 9 + app/views/products/who_bought.xml.builder | 8 + app/views/sessions/create.html.erb | 2 + app/views/sessions/destroy.html.erb | 2 + app/views/sessions/new.html.erb | 25 ++ app/views/store/index.html.haml | 14 + app/views/users/_form.html.erb | 41 +++ app/views/users/edit.html.erb | 6 + app/views/users/index.html.erb | 29 ++ app/views/users/new.html.erb | 5 + app/views/users/show.html.erb | 15 + config.ru | 4 + config/application.rb | 67 +++++ config/boot.rb | 14 + config/database.yml | 31 +++ config/deploy.rb | 65 +++++ config/environment.rb | 13 + config/environments/development.rb | 60 ++++ config/environments/production.rb | 78 ++++++ config/environments/test.rb | 45 +++ config/initializers/backtrace_silencers.rb | 15 + config/initializers/i18n.rb | 15 + config/initializers/inflections.rb | 27 ++ config/initializers/mime_types.rb | 13 + config/initializers/secret_token.rb | 15 + config/initializers/session_store.rb | 16 ++ config/initializers/wrap_parameters.rb | 22 ++ config/locales/en.yml | 73 +++++ config/locales/es.yml | 94 +++++++ config/routes.rb | 31 +++ db/backup/production.backup | 3 + db/migrate/20110711000001_create_products.rb | 20 ++ db/migrate/20110711000002_create_carts.rb | 16 ++ .../20110711000003_create_line_items.rb | 18 ++ ...110711000004_add_quantity_to_line_items.rb | 14 + .../20110711000005_combine_items_in_cart.rb | 42 +++ .../20110711000006_add_price_to_line_item.rb | 17 ++ db/migrate/20110711000007_create_orders.rb | 20 ++ ...0110711000008_add_order_id_to_line_item.rb | 14 + db/migrate/20110711000009_create_users.rb | 18 ++ db/production.db | 0 db/schema.rb | 64 +++++ db/seeds.rb | 45 +++ doc/README_FOR_APP | 37 +++ lib/assets/.gitkeep | 0 lib/tasks/.gitkeep | 0 lib/tasks/db_backup.rake | 14 + lib/tasks/db_schema_migrations.rake | 7 + public/404.html | 34 +++ public/422.html | 34 +++ public/500.html | 33 +++ public/favicon.ico | 0 public/robots.txt | 5 + script/creditcard.rb | 18 ++ script/load_orders.rb | 14 + script/rails | 6 + store.ru | 10 + test/fixtures/.gitkeep | 0 test/fixtures/carts.yml | 11 + test/fixtures/line_items.yml | 12 + test/fixtures/orders.yml | 20 ++ test/fixtures/products.yml | 25 ++ test/fixtures/users.yml | 10 + test/functional/.gitkeep | 0 test/functional/admin_controller_test.rb | 17 ++ test/functional/carts_controller_test.rb | 58 ++++ test/functional/line_items_controller_test.rb | 68 +++++ test/functional/order_notifier_test.rb | 29 ++ test/functional/orders_controller_test.rb | 67 +++++ test/functional/products_controller_test.rb | 77 ++++++ test/functional/sessions_controller_test.rb | 35 +++ test/functional/store_controller_test.rb | 26 ++ test/functional/users_controller_test.rb | 65 +++++ test/integration/.gitkeep | 0 test/integration/dsl_user_stories_test.rb | 128 +++++++++ test/integration/user_stories_test.rb | 67 +++++ test/performance/browsing_test.rb | 20 ++ test/test_helper.rb | 33 +++ test/unit/.gitkeep | 0 test/unit/cart_test.rb | 32 +++ test/unit/helpers/admin_helper_test.rb | 12 + test/unit/helpers/carts_helper_test.rb | 12 + test/unit/helpers/line_items_helper_test.rb | 12 + test/unit/helpers/orders_helper_test.rb | 12 + test/unit/helpers/products_helper_test.rb | 12 + test/unit/helpers/sessions_helper_test.rb | 12 + test/unit/helpers/store_helper_test.rb | 12 + test/unit/helpers/users_helper_test.rb | 12 + test/unit/line_item_test.rb | 15 + test/unit/order_test.rb | 15 + test/unit/product_test.rb | 81 ++++++ test/unit/routing_test.rb | 50 ++++ test/unit/user_test.rb | 15 + vendor/assets/javascripts/.gitkeep | 0 vendor/assets/stylesheets/.gitkeep | 0 vendor/cache/i18n-0.6.0.gem | Bin 0 -> 60928 bytes vendor/cache/multi_json-1.0.4.gem | Bin 0 -> 14336 bytes vendor/cache/rake-0.9.2.2.gem | Bin 0 -> 111616 bytes 184 files changed, 4617 insertions(+) create mode 100644 Capfile create mode 100644 Gemfile create mode 100644 README.rdoc create mode 100644 Rakefile create mode 100644 app/assets/images/cs.jpg create mode 100644 app/assets/images/logo.png create mode 100644 app/assets/images/rails.png create mode 100644 app/assets/images/rtp.jpg create mode 100644 app/assets/images/ruby.jpg create mode 100644 app/assets/javascripts/admin.js.coffee create mode 100644 app/assets/javascripts/application.js create mode 100644 app/assets/javascripts/carts.js.coffee create mode 100644 app/assets/javascripts/line_items.js.coffee create mode 100644 app/assets/javascripts/orders.js.coffee create mode 100644 app/assets/javascripts/products.js.coffee create mode 100644 app/assets/javascripts/sessions.js.coffee create mode 100644 app/assets/javascripts/store.js.coffee create mode 100644 app/assets/javascripts/users.js.coffee create mode 100644 app/assets/stylesheets/admin.css.scss create mode 100644 app/assets/stylesheets/application.css.scss create mode 100644 app/assets/stylesheets/carts.css.scss create mode 100644 app/assets/stylesheets/line_items.css.scss create mode 100644 app/assets/stylesheets/orders.css.scss create mode 100644 app/assets/stylesheets/products.css.scss create mode 100644 app/assets/stylesheets/scaffolds.css.scss create mode 100644 app/assets/stylesheets/sessions.css.scss create mode 100644 app/assets/stylesheets/store.css.scss create mode 100644 app/assets/stylesheets/users.css.scss create mode 100644 app/controllers/admin_controller.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/carts_controller.rb create mode 100644 app/controllers/line_items_controller.rb create mode 100644 app/controllers/orders_controller.rb create mode 100644 app/controllers/products_controller.rb create mode 100644 app/controllers/sessions_controller.rb create mode 100644 app/controllers/store_controller.rb create mode 100644 app/controllers/users_controller.rb create mode 100644 app/helpers/admin_helper.rb create mode 100644 app/helpers/application_helper.rb create mode 100644 app/helpers/carts_helper.rb create mode 100644 app/helpers/line_items_helper.rb create mode 100644 app/helpers/orders_helper.rb create mode 100644 app/helpers/products_helper.rb create mode 100644 app/helpers/sessions_helper.rb create mode 100644 app/helpers/store_helper.rb create mode 100644 app/helpers/users_helper.rb create mode 100644 app/mailers/.gitkeep create mode 100644 app/mailers/order_notifier.rb create mode 100644 app/models/.gitkeep create mode 100644 app/models/cart.rb create mode 100644 app/models/line_item.rb create mode 100644 app/models/order.rb create mode 100644 app/models/product.rb create mode 100644 app/models/user.rb create mode 100644 app/store.rb create mode 100644 app/views/admin/index.html.erb create mode 100644 app/views/carts/_cart.html.erb create mode 100644 app/views/carts/_form.html.erb create mode 100644 app/views/carts/edit.html.erb create mode 100644 app/views/carts/index.html.erb create mode 100644 app/views/carts/new.html.erb create mode 100644 app/views/carts/show.html.erb create mode 100644 app/views/layouts/application.html.erb create mode 100644 app/views/line_items/_form.html.erb create mode 100644 app/views/line_items/_line_item.html.erb create mode 100644 app/views/line_items/_line_item.text.erb create mode 100644 app/views/line_items/create.js.erb create mode 100644 app/views/line_items/edit.html.erb create mode 100644 app/views/line_items/index.html.erb create mode 100644 app/views/line_items/new.html.erb create mode 100644 app/views/line_items/show.html.erb create mode 100644 app/views/order_notifier/received.text.erb create mode 100644 app/views/order_notifier/shipped.html.erb create mode 100644 app/views/order_notifier/shipped.text.erb create mode 100644 app/views/orders/_form.html.erb create mode 100644 app/views/orders/edit.html.erb create mode 100644 app/views/orders/index.html.erb create mode 100644 app/views/orders/new.html.erb create mode 100644 app/views/orders/show.html.erb create mode 100644 app/views/products/_form.html.erb create mode 100644 app/views/products/edit.html.erb create mode 100644 app/views/products/index.html.erb create mode 100644 app/views/products/index.xml.builder create mode 100644 app/views/products/new.html.erb create mode 100644 app/views/products/show.html.erb create mode 100644 app/views/products/who_bought.atom.builder create mode 100644 app/views/products/who_bought.html.erb create mode 100644 app/views/products/who_bought.xml.builder create mode 100644 app/views/sessions/create.html.erb create mode 100644 app/views/sessions/destroy.html.erb create mode 100644 app/views/sessions/new.html.erb create mode 100644 app/views/store/index.html.haml create mode 100644 app/views/users/_form.html.erb create mode 100644 app/views/users/edit.html.erb create mode 100644 app/views/users/index.html.erb create mode 100644 app/views/users/new.html.erb create mode 100644 app/views/users/show.html.erb create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/database.yml create mode 100644 config/deploy.rb create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/i18n.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/secret_token.rb create mode 100644 config/initializers/session_store.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/locales/es.yml create mode 100644 config/routes.rb create mode 100644 db/backup/production.backup create mode 100644 db/migrate/20110711000001_create_products.rb create mode 100644 db/migrate/20110711000002_create_carts.rb create mode 100644 db/migrate/20110711000003_create_line_items.rb create mode 100644 db/migrate/20110711000004_add_quantity_to_line_items.rb create mode 100644 db/migrate/20110711000005_combine_items_in_cart.rb create mode 100644 db/migrate/20110711000006_add_price_to_line_item.rb create mode 100644 db/migrate/20110711000007_create_orders.rb create mode 100644 db/migrate/20110711000008_add_order_id_to_line_item.rb create mode 100644 db/migrate/20110711000009_create_users.rb create mode 100644 db/production.db create mode 100644 db/schema.rb create mode 100644 db/seeds.rb create mode 100644 doc/README_FOR_APP create mode 100644 lib/assets/.gitkeep create mode 100644 lib/tasks/.gitkeep create mode 100644 lib/tasks/db_backup.rake create mode 100644 lib/tasks/db_schema_migrations.rake create mode 100644 public/404.html create mode 100644 public/422.html create mode 100644 public/500.html create mode 100644 public/favicon.ico create mode 100644 public/robots.txt create mode 100644 script/creditcard.rb create mode 100644 script/load_orders.rb create mode 100755 script/rails create mode 100644 store.ru create mode 100644 test/fixtures/.gitkeep create mode 100644 test/fixtures/carts.yml create mode 100644 test/fixtures/line_items.yml create mode 100644 test/fixtures/orders.yml create mode 100644 test/fixtures/products.yml create mode 100644 test/fixtures/users.yml create mode 100644 test/functional/.gitkeep create mode 100644 test/functional/admin_controller_test.rb create mode 100644 test/functional/carts_controller_test.rb create mode 100644 test/functional/line_items_controller_test.rb create mode 100644 test/functional/order_notifier_test.rb create mode 100644 test/functional/orders_controller_test.rb create mode 100644 test/functional/products_controller_test.rb create mode 100644 test/functional/sessions_controller_test.rb create mode 100644 test/functional/store_controller_test.rb create mode 100644 test/functional/users_controller_test.rb create mode 100644 test/integration/.gitkeep create mode 100644 test/integration/dsl_user_stories_test.rb create mode 100644 test/integration/user_stories_test.rb create mode 100644 test/performance/browsing_test.rb create mode 100644 test/test_helper.rb create mode 100644 test/unit/.gitkeep create mode 100644 test/unit/cart_test.rb create mode 100644 test/unit/helpers/admin_helper_test.rb create mode 100644 test/unit/helpers/carts_helper_test.rb create mode 100644 test/unit/helpers/line_items_helper_test.rb create mode 100644 test/unit/helpers/orders_helper_test.rb create mode 100644 test/unit/helpers/products_helper_test.rb create mode 100644 test/unit/helpers/sessions_helper_test.rb create mode 100644 test/unit/helpers/store_helper_test.rb create mode 100644 test/unit/helpers/users_helper_test.rb create mode 100644 test/unit/line_item_test.rb create mode 100644 test/unit/order_test.rb create mode 100644 test/unit/product_test.rb create mode 100644 test/unit/routing_test.rb create mode 100644 test/unit/user_test.rb create mode 100644 vendor/assets/javascripts/.gitkeep create mode 100644 vendor/assets/stylesheets/.gitkeep create mode 100644 vendor/cache/i18n-0.6.0.gem create mode 100644 vendor/cache/multi_json-1.0.4.gem create mode 100644 vendor/cache/rake-0.9.2.2.gem diff --git a/Capfile b/Capfile new file mode 100644 index 0000000..3e8d828 --- /dev/null +++ b/Capfile @@ -0,0 +1,11 @@ +load 'deploy' if respond_to?(:namespace) # cap2 differentiator + +# Uncomment if you are using Rails' asset pipeline +#START_HIGHLIGHT +load 'deploy/assets' +#END_HIGHLIGHT + +Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb']. + each { |plugin| load(plugin) } + +load 'config/deploy' # remove this line to skip loading any of the default tasks \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..fa5bad0 --- /dev/null +++ b/Gemfile @@ -0,0 +1,53 @@ +source 'https://rubygems.org' + +gem 'rails', '3.2.0' + +# Bundle edge Rails instead: +# gem 'rails', :git => 'git://github.com/rails/rails.git' + +gem 'sqlite3' +group :production do + gem 'mysql2' +end + + +# Gems used only for assets and not required +# in production environments by default. +group :assets do + gem 'sass-rails', '~> 3.2.3' + gem 'coffee-rails', '~> 3.2.1' + + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + # gem 'therubyracer' + + gem 'uglifier', '>= 1.0.3' +end + +gem 'jquery-rails' + +# To use ActiveModel has_secure_password +gem 'bcrypt-ruby', '~> 3.0.0' + +# To use Jbuilder templates for JSON +# gem 'jbuilder' + +# Use unicorn as the web server +# gem 'unicorn' + +# Deploy with Capistrano +gem 'capistrano' + +# To use debugger +# gem 'ruby-debug19', :require => 'ruby-debug' + +gem 'will_paginate', '~> 3.0' + +#START:plugins +#START_HIGHLIGHT +gem 'activemerchant' +#START_HIGHLIGHT +gem 'haml', '~> 3.1.1' +#END_HIGHLIGHT +#END_HIGHLIGHT +#END:plugins + diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000..7c36f23 --- /dev/null +++ b/README.rdoc @@ -0,0 +1,261 @@ +== Welcome to Rails + +Rails is a web-application framework that includes everything needed to create +database-backed web applications according to the Model-View-Control pattern. + +This pattern splits the view (also called the presentation) into "dumb" +templates that are primarily responsible for inserting pre-built data in between +HTML tags. The model contains the "smart" domain objects (such as Account, +Product, Person, Post) that holds all the business logic and knows how to +persist themselves to a database. The controller handles the incoming requests +(such as Save New Account, Update Product, Show Post) by manipulating the model +and directing data to the view. + +In Rails, the model is handled by what's called an object-relational mapping +layer entitled Active Record. This layer allows you to present the data from +database rows as objects and embellish these data objects with business logic +methods. You can read more about Active Record in +link:files/vendor/rails/activerecord/README.html. + +The controller and view are handled by the Action Pack, which handles both +layers by its two parts: Action View and Action Controller. These two layers +are bundled in a single package due to their heavy interdependence. This is +unlike the relationship between the Active Record and Action Pack that is much +more separate. Each of these packages can be used independently outside of +Rails. You can read more about Action Pack in +link:files/vendor/rails/actionpack/README.html. + + +== Getting Started + +1. At the command prompt, create a new Rails application: + rails new myapp (where myapp is the application name) + +2. Change directory to myapp and start the web server: + cd myapp; rails server (run with --help for options) + +3. Go to http://localhost:3000/ and you'll see: + "Welcome aboard: You're riding Ruby on Rails!" + +4. Follow the guidelines to start developing your application. You can find +the following resources handy: + +* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html +* Ruby on Rails Tutorial Book: http://www.railstutorial.org/ + + +== Debugging Rails + +Sometimes your application goes wrong. Fortunately there are a lot of tools that +will help you debug it and get it back on the rails. + +First area to check is the application log files. Have "tail -f" commands +running on the server.log and development.log. Rails will automatically display +debugging and runtime information to these files. Debugging info will also be +shown in the browser on requests from 127.0.0.1. + +You can also log your own messages directly into the log file from your code +using the Ruby logger class from inside your controllers. Example: + + class WeblogController < ActionController::Base + def destroy + @weblog = Weblog.find(params[:id]) + @weblog.destroy + logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") + end + end + +The result will be a message in your log file along the lines of: + + Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! + +More information on how to use the logger is at http://www.ruby-doc.org/core/ + +Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are +several books available online as well: + +* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) +* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) + +These two books will bring you up to speed on the Ruby language and also on +programming in general. + + +== Debugger + +Debugger support is available through the debugger command when you start your +Mongrel or WEBrick server with --debugger. This means that you can break out of +execution at any point in the code, investigate and change the model, and then, +resume execution! You need to install ruby-debug to run the server in debugging +mode. With gems, use sudo gem install ruby-debug. Example: + + class WeblogController < ActionController::Base + def index + @posts = Post.all + debugger + end + end + +So the controller will accept the action, run the first line, then present you +with a IRB prompt in the server window. Here you can do things like: + + >> @posts.inspect + => "[#nil, "body"=>nil, "id"=>"1"}>, + #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" + >> @posts.first.title = "hello from a debugger" + => "hello from a debugger" + +...and even better, you can examine how your runtime objects actually work: + + >> f = @posts.first + => #nil, "body"=>nil, "id"=>"1"}> + >> f. + Display all 152 possibilities? (y or n) + +Finally, when you're ready to resume execution, you can enter "cont". + + +== Console + +The console is a Ruby shell, which allows you to interact with your +application's domain model. Here you'll have all parts of the application +configured, just like it is when the application is running. You can inspect +domain models, change values, and save to the database. Starting the script +without arguments will launch it in the development environment. + +To start the console, run rails console from the application +directory. + +Options: + +* Passing the -s, --sandbox argument will rollback any modifications + made to the database. +* Passing an environment name as an argument will load the corresponding + environment. Example: rails console production. + +To reload your controllers and models after launching the console run +reload! + +More information about irb can be found at: +link:http://www.rubycentral.org/pickaxe/irb.html + + +== dbconsole + +You can go to the command line of your database directly through rails +dbconsole. You would be connected to the database with the credentials +defined in database.yml. Starting the script without arguments will connect you +to the development database. Passing an argument will connect you to a different +database, like rails dbconsole production. Currently works for MySQL, +PostgreSQL and SQLite 3. + +== Description of Contents + +The default directory structure of a generated Ruby on Rails application: + + |-- app + | |-- assets + | |-- images + | |-- javascripts + | `-- stylesheets + | |-- controllers + | |-- helpers + | |-- mailers + | |-- models + | `-- views + | `-- layouts + |-- config + | |-- environments + | |-- initializers + | `-- locales + |-- db + |-- doc + |-- lib + | `-- tasks + |-- log + |-- public + |-- script + |-- test + | |-- fixtures + | |-- functional + | |-- integration + | |-- performance + | `-- unit + |-- tmp + | |-- cache + | |-- pids + | |-- sessions + | `-- sockets + `-- vendor + |-- assets + `-- stylesheets + `-- plugins + +app + Holds all the code that's specific to this particular application. + +app/assets + Contains subdirectories for images, stylesheets, and JavaScript files. + +app/controllers + Holds controllers that should be named like weblogs_controller.rb for + automated URL mapping. All controllers should descend from + ApplicationController which itself descends from ActionController::Base. + +app/models + Holds models that should be named like post.rb. Models descend from + ActiveRecord::Base by default. + +app/views + Holds the template files for the view that should be named like + weblogs/index.html.erb for the WeblogsController#index action. All views use + eRuby syntax by default. + +app/views/layouts + Holds the template files for layouts to be used with views. This models the + common header/footer method of wrapping views. In your views, define a layout + using the layout :default and create a file named default.html.erb. + Inside default.html.erb, call <% yield %> to render the view using this + layout. + +app/helpers + Holds view helpers that should be named like weblogs_helper.rb. These are + generated for you automatically when using generators for controllers. + Helpers can be used to wrap functionality for your views into methods. + +config + Configuration files for the Rails environment, the routing map, the database, + and other dependencies. + +db + Contains the database schema in schema.rb. db/migrate contains all the + sequence of Migrations for your schema. + +doc + This directory is where your application documentation will be stored when + generated using rake doc:app + +lib + Application specific libraries. Basically, any kind of custom code that + doesn't belong under controllers, models, or helpers. This directory is in + the load path. + +public + The directory available for the web server. Also contains the dispatchers and the + default HTML files. This should be set as the DOCUMENT_ROOT of your web + server. + +script + Helper scripts for automation and generation. + +test + Unit and functional tests along with fixtures. When using the rails generate + command, template test files will be generated for you and placed in this + directory. + +vendor + External libraries that the application depends on. Also includes the plugins + subdirectory. If the app has frozen rails, those gems also go here, under + vendor/rails/. This directory is in the load path. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..b2edff9 --- /dev/null +++ b/Rakefile @@ -0,0 +1,7 @@ +#!/usr/bin/env rake +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Depot::Application.load_tasks diff --git a/app/assets/images/cs.jpg b/app/assets/images/cs.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a51016c90b503ef3fa3f494c0423f00d4b67072 GIT binary patch literal 15093 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..19dc3452a86ecd23e99dead07530658e06db450a GIT binary patch literal 1040 zcmV+r1n>KaP)?+#XpmBmx0LjAN`&8!!iS41uE+k-2Rn8{`Vd?Zixmv z09}&CNES&+Gk~OILr5AeIaHzqz$yix3ai3W2C5_bG&hgKuvVZbVA=W7q-iZ0r2(M? z#}a($UP}{|2DlPKQ6y#OtZ+swE_QmBi_>vfW`Mi2PC)Yjf&i8?8Uf;gMu2ZXD1dhW z2~at2mrj6{r@3J_98Umi%>d9804#ao3@^w%Y&S`OSO5g?dwb(14xjp)!+fuC7{;{u z`^wc4a^(!$#VfA4O)Thwo0&f4+HrrSWoOoPJPx~n*HUf-pm}8CgrfEDV7vgKAhAVl z4M?0exb%$tvA@;~fA#XR?2K8>dRm9$Nw^09@LU`aN^7Bu3x&B+_FRH1thTdcUz&vC zD|(aASZb2u#eQ+Vi&@VahSK>VKYs}toMb%T5ae8#G;`SQkUpkhGjsDR$HPL2ec+69Y~$5c%VCk;%~TV zy4QSK&3d0`7Vo7K&;^K`hyfIZWw=%WR|4X>!)30ZqDq|59nke=KYHZv7)P^?kMmra z5(gl2XaYb4mOV!RnYd^^`^y$hLI~kK?uEa{v%h1WcKbtp$VHdT4oDnZ+d7Knpv3|) zB`xiZEAm!X_uSon+3%NgtJ?fMU>?W$b_M5iT`8IXTC#FRcEgV;X z-kC2RG-!()@AmK{Tw3d0f!dqz7VyP4g>5W}xKJ%3UE#UAD%>onOLOqtgXiw<&KvWu z|DnUL!-cMb>-coXjlaL7=`$Us!*qC8r=S0YAMS@I;E(kA>wf^#z=VWtCLdthj)A!BBmWB&y|X`RY;f`BJ<_ju%@N||NoLFD~mQl$aHGjq>;5dG_D{h(5s}0 z6&=HANU$m__3PuddU(lvR_xWj`}Oho@9EyQt-n!E*P(KhM@X_VFV2l&>deNZJT%y8iwA zoG>u1B`p2=_u9k4v1Mud`1+qvOZoHg#bITJ9U`qBAek?40RR96!AV3xRCwBy*IQ$v zN(=yC9IhRft9V64L`77pqF_Cx@c;kSNoGK)`?Ps*cP(EtGlYZ{D5cxspMQvjKH)Oh6X(pa|J{ zGy1J$Ej7=Z{uvmMfRRsE;v`p;45B~6*ep#hM^ji zl$+7qoWq~}ewG=61uFw0He{tJurMU&4Iv?=B^eR(wAHk!miA)O7p_+YR>lbmU3rmn ze?+ze(+sEd6foB&*l9+?zkr_a-5*v&p*?c}HOGtyHg6r{WFYpQ=#z0Hc7VWLx$>M3|b0|Gn z+5t#z6*ffSVc6DjpmB2?AAR@@vB!wCK?9Yl;33;Q7^%(401QW|k=R8b!OwtLJPjjm zO9Ia;qCq)rOq!1Ia*6#A%#xb}yDx1P*pWla>9j$bnMn3CBqe4`TRll_Iy29kmG?4fbKuF=XqU|?3b@B zA`&a?KIgZ|KJx5eND_c3Em=WZn@xW8hRJ^G&sY^b(FW?WC9W_sb;+lAPdLTdBaKIK;-f}*h4|1aTjw7qX_k~e{TWO7jqcekERN;Jyh%67)q4rKpL*CEYL;|#GY{B@5 zi52XoC?xsoorJKxsliugF#z38MJqrYCWV(t<=G&f;^Me13&AiI9{3jUZ$ zFM`*L(9qc^VMxkz1oaDH!1pcD^IXp>Z0Jb=_qs?Vsrs{mp<^{$N!EC9o+`CO-(o}E zJ`y{*;9s|wr22-QoJ87y^~;)Q@b%P4UgSSsx>2$o@Vd{%Pk0@4qZ^fhB(vt$c1TG> z*{Ad;foraENbld`=MCNm4?9kvlgK~&J>ialpJ7nua zx0oRzwG5;}Qne)Fg(N3kf?JVmB;}y&5(0+~r*aL$0Zof8fe!AtHWH>A^1Y)@G@GsA zup`R{Qg?{+MaxTq#2n{6w|)c&yaJ7{U4ngAH5v6I)*;@rEBE*ehIPBwKBQU)YKE8F0lR!Sm?sE4Xk-sj&E$|A-9n dP56HS1^^A-61FoN)nxzx002ovPDHLkV1kw_Sd9Px literal 0 HcmV?d00001 diff --git a/app/assets/images/rtp.jpg b/app/assets/images/rtp.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cbaafdda165e918cc324e72e5f9dfe0e3f7984cb GIT binary patch literal 9882 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 J9MfKn{V%z@jgtTX literal 0 HcmV?d00001 diff --git a/app/assets/images/ruby.jpg b/app/assets/images/ruby.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34d5e5b05b250e603af2aac47c57e8ba225131f2 GIT binary patch literal 8300 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 V|A#pLl1|TnCEMVC=zKl + $('.store .entry > img').click -> + $(this).parent().find(':submit').click() +//#END_HIGHLIGHT diff --git a/app/assets/javascripts/users.js.coffee b/app/assets/javascripts/users.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/users.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/admin.css.scss b/app/assets/stylesheets/admin.css.scss new file mode 100644 index 0000000..0f4f3b2 --- /dev/null +++ b/app/assets/stylesheets/admin.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Admin controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss new file mode 100644 index 0000000..4344b8b --- /dev/null +++ b/app/assets/stylesheets/application.css.scss @@ -0,0 +1,135 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will + * include all the files listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, + * vendor/assets/stylesheets, or vendor/assets/stylesheets of plugins, if any, + * can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear + * at the top of the compiled file, but it's generally better to create a new + * file per style scope. + * + *= require_self + *= require_tree . +*/ + +#banner { + background: #9c9; + padding: 10px; + border-bottom: 2px solid; + font: small-caps 40px/40px "Times New Roman", serif; + color: #282; + text-align: center; + + img { + float: left; + } +} + +#notice { + color: #000 !important; + border: 2px solid red; + padding: 1em; + margin-bottom: 2em; + background-color: #f0f0f0; + font: bold smaller sans-serif; +} + +#columns { + background: #141; + + #main { + margin-left: 17em; + padding: 1em; + background: white; + } + +//#START:side + #side { + float: left; + padding: 1em 2em; + width: 13em; + background: #141; + +/* START_HIGHLIGHT */ + form, div { + display: inline; + } + + input { + font-size: small; + } + + #cart { + font-size: smaller; + color: white; + + table { + border-top: 1px dotted #595; + border-bottom: 1px dotted #595; + margin-bottom: 10px; + } + } + +/* END_HIGHLIGHT */ + ul { + padding: 0; + + li { + list-style: none; + + a { + color: #bfb; + font-size: small; + } + } + } + } +//#END:side +} + +//#START:form +.depot_form { + fieldset { + background: #efe; + + legend { + color: #dfd; + background: #141; + font-family: sans-serif; + padding: 0.2em 1em; + } + } + + form { + label { + width: 5em; + float: left; + text-align: right; + padding-top: 0.2em; + margin-right: 0.1em; + display: block; + } + + select, textarea, input { + margin-left: 0.5em; + } + + .submit { + margin-left: 4em; + } + + br { + display: none + } + } +} +//#END:form + +/* START:i18n */ +.locale { + float: right; + margin: -0.25em 0.1em; +} +/* END:i18n */ diff --git a/app/assets/stylesheets/carts.css.scss b/app/assets/stylesheets/carts.css.scss new file mode 100644 index 0000000..f95d429 --- /dev/null +++ b/app/assets/stylesheets/carts.css.scss @@ -0,0 +1,20 @@ +// Place all the styles related to the Carts controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +/* START_HIGHLIGHT */ +.carts, #side #cart { +/* END_HIGHLIGHT */ + .cart_title { + font: 120% bold; + } + + .item_price, .total_line { + text-align: right; + } + + .total_line .total_cell { + font-weight: bold; + border-top: 1px solid #595; + } +} diff --git a/app/assets/stylesheets/line_items.css.scss b/app/assets/stylesheets/line_items.css.scss new file mode 100644 index 0000000..d7c9df4 --- /dev/null +++ b/app/assets/stylesheets/line_items.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the LineItems controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/orders.css.scss b/app/assets/stylesheets/orders.css.scss new file mode 100644 index 0000000..7415069 --- /dev/null +++ b/app/assets/stylesheets/orders.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Orders controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/products.css.scss b/app/assets/stylesheets/products.css.scss new file mode 100644 index 0000000..d8313c6 --- /dev/null +++ b/app/assets/stylesheets/products.css.scss @@ -0,0 +1,53 @@ +// Place all the styles related to the Products controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +/* START_HIGHLIGHT */ +.products { + table { + border-collapse: collapse; + } + + table tr td { + padding: 5px; + vertical-align: top; + } + + .list_image { + width: 60px; + height: 70px; + } + + .list_description { + width: 60%; + + dl { + margin: 0; + } + + dt { + color: #244; + font-weight: bold; + font-size: larger; + } + + dd { + margin: 0; + } + } + + .list_actions { + font-size: x-small; + text-align: right; + padding-left: 1em; + } + + .list_line_even { + background: #e0f8f8; + } + + .list_line_odd { + background: #f8b0f8; + } +} +/* END_HIGHLIGHT */ diff --git a/app/assets/stylesheets/scaffolds.css.scss b/app/assets/stylesheets/scaffolds.css.scss new file mode 100644 index 0000000..05188f0 --- /dev/null +++ b/app/assets/stylesheets/scaffolds.css.scss @@ -0,0 +1,56 @@ +body { + background-color: #fff; + color: #333; + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; } + +p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; } + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; } + +a { + color: #000; + &:visited { + color: #666; } + &:hover { + color: #fff; + background-color: #000; } } + +div { + &.field, &.actions { + margin-bottom: 10px; } } + +#notice { + color: green; } + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; } + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px; + padding-bottom: 0; + margin-bottom: 20px; + background-color: #f0f0f0; + h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + margin-bottom: 0px; + background-color: #c00; + color: #fff; } + ul li { + font-size: 12px; + list-style: square; } } diff --git a/app/assets/stylesheets/sessions.css.scss b/app/assets/stylesheets/sessions.css.scss new file mode 100644 index 0000000..ccb1ed2 --- /dev/null +++ b/app/assets/stylesheets/sessions.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Sessions controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/store.css.scss b/app/assets/stylesheets/store.css.scss new file mode 100644 index 0000000..48d3ea4 --- /dev/null +++ b/app/assets/stylesheets/store.css.scss @@ -0,0 +1,57 @@ +// Place all the styles related to the Store controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +/* START_HIGHLIGHT */ +.store { + h1 { + margin: 0; + padding-bottom: 0.5em; + font: 150% sans-serif; + color: #226; + border-bottom: 3px dotted #77d; + } + + /* An entry in the store catalog */ + .entry { + overflow: auto; + margin-top: 1em; + border-bottom: 1px dotted #77d; + min-height: 100px; + + img { + width: 80px; + margin-right: 5px; + margin-bottom: 5px; + position: absolute; + } + + h3 { + font-size: 120%; + font-family: sans-serif; + margin-left: 100px; + margin-top: 0; + margin-bottom: 2px; + color: #227; + } + +//#START:inline + p, div.price_line { + margin-left: 100px; + margin-top: 0.5em; + margin-bottom: 0.8em; + + form, div { + display: inline; + } + } +//#END:inline + + .price { + color: #44a; + font-weight: bold; + margin-right: 3em; + } + } +} +/* END_HIGHLIGHT */ diff --git a/app/assets/stylesheets/users.css.scss b/app/assets/stylesheets/users.css.scss new file mode 100644 index 0000000..31a2eac --- /dev/null +++ b/app/assets/stylesheets/users.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Users controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb new file mode 100644 index 0000000..f823082 --- /dev/null +++ b/app/controllers/admin_controller.rb @@ -0,0 +1,13 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class AdminController < ApplicationController + def index + @total_orders = Order.count + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..0378048 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,57 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class ApplicationController < ActionController::Base + before_filter :set_i18n_locale_from_params + # ... + before_filter :authorize + protect_from_forgery + + private + + def current_cart + Cart.find(session[:cart_id]) + rescue ActiveRecord::RecordNotFound + cart = Cart.create + session[:cart_id] = cart.id + cart + end + + # ... + + protected + + def authorize + if request.format == Mime::HTML + unless User.find_by_id(session[:user_id]) + redirect_to login_url, notice: "Please log in" + end + else + authenticate_or_request_with_http_basic do |username, password| + user = User.find_by_name(username) + user && user.authenticate(password) + end + end + end + + def set_i18n_locale_from_params + if params[:locale] + if I18n.available_locales.include?(params[:locale].to_sym) + I18n.locale = params[:locale] + else + flash.now[:notice] = + "#{params[:locale]} translation not available" + logger.error flash.now[:notice] + end + end + end + + def default_url_options + { locale: I18n.locale } + end +end diff --git a/app/controllers/carts_controller.rb b/app/controllers/carts_controller.rb new file mode 100644 index 0000000..d5ecb86 --- /dev/null +++ b/app/controllers/carts_controller.rb @@ -0,0 +1,99 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class CartsController < ApplicationController + skip_before_filter :authorize, only: [:create, :update, :destroy] + + # GET /carts + # GET /carts.json + def index + @carts = Cart.all + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @carts } + end + end + + # GET /carts/1 + # GET /carts/1.json + def show + begin + @cart = Cart.find(params[:id]) + rescue ActiveRecord::RecordNotFound + logger.error "Attempt to access invalid cart #{params[:id]}" + redirect_to store_url, notice: 'Invalid cart' + else + respond_to do |format| + format.html # show.html.erb + format.json { render json: @cart } + end + end + end + + # GET /carts/new + # GET /carts/new.json + def new + @cart = Cart.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @cart } + end + end + + # GET /carts/1/edit + def edit + @cart = Cart.find(params[:id]) + end + + # POST /carts + # POST /carts.json + def create + @cart = Cart.new(params[:cart]) + + respond_to do |format| + if @cart.save + format.html { redirect_to @cart, notice: 'Cart was successfully created.' } + format.json { render json: @cart, status: :created, location: @cart } + else + format.html { render action: "new" } + format.json { render json: @cart.errors, status: :unprocessable_entity } + end + end + end + + # PUT /carts/1 + # PUT /carts/1.json + def update + @cart = Cart.find(params[:id]) + + respond_to do |format| + if @cart.update_attributes(params[:cart]) + format.html { redirect_to @cart, notice: 'Cart was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @cart.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /carts/1 + # DELETE /carts/1.json + def destroy + @cart = current_cart + @cart.destroy + session[:cart_id] = nil + + respond_to do |format| + format.html { redirect_to store_url } + format.json { head :no_content } + end + end +end diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb new file mode 100644 index 0000000..beeffb6 --- /dev/null +++ b/app/controllers/line_items_controller.rb @@ -0,0 +1,106 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class LineItemsController < ApplicationController + skip_before_filter :authorize, only: :create + + # GET /line_items + # GET /line_items.json + def index + @line_items = LineItem.all + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @line_items } + format.xml { render xml: @line_items } + end + end + + # GET /line_items/1 + # GET /line_items/1.json + def show + @line_item = LineItem.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @line_item } + end + end + + # GET /line_items/new + # GET /line_items/new.json + def new + @line_item = LineItem.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @line_item } + end + end + + # GET /line_items/1/edit + def edit + @line_item = LineItem.find(params[:id]) + end + + # POST /line_items + # POST /line_items.json + def create + @cart = current_cart + if params[:line_item] + # ActiveResource + params[:line_item][:order_id] = params[:order_id] + @line_item = LineItem.new(params[:line_item]) + else + # HTML forms + product = Product.find(params[:product_id]) + @line_item = @cart.add_product(product.id) + end + + respond_to do |format| + if @line_item.save + format.html { redirect_to store_url } + format.js { @current_item = @line_item } + format.json { render json: @line_item, + status: :created, location: @line_item } + else + format.html { render action: "new" } + format.json { render json: @line_item.errors, + status: :unprocessable_entity } + end + end + end + + # PUT /line_items/1 + # PUT /line_items/1.json + def update + @line_item = LineItem.find(params[:id]) + + respond_to do |format| + if @line_item.update_attributes(params[:line_item]) + format.html { redirect_to @line_item, notice: 'Line item was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @line_item.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /line_items/1 + # DELETE /line_items/1.json + def destroy + @line_item = LineItem.find(params[:id]) + @line_item.destroy + + respond_to do |format| + format.html { redirect_to line_items_url } + format.json { head :no_content } + end + end +end diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb new file mode 100644 index 0000000..3307fc8 --- /dev/null +++ b/app/controllers/orders_controller.rb @@ -0,0 +1,108 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class OrdersController < ApplicationController + skip_before_filter :authorize, only: [:new, :create] + + # GET /orders + # GET /orders.json + def index + @orders = Order.paginate page: params[:page], order: 'created_at desc', + per_page: 10 + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @orders } + end + end + + # GET /orders/1 + # GET /orders/1.json + def show + @order = Order.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @order } + end + end + + # GET /orders/new + # GET /orders/new.json + def new + @cart = current_cart + if @cart.line_items.empty? + redirect_to store_url, notice: "Your cart is empty" + return + end + + @order = Order.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @order } + end + end + + # GET /orders/1/edit + def edit + @order = Order.find(params[:id]) + end + + # POST /orders + # POST /orders.json + def create + @order = Order.new(params[:order]) + @order.add_line_items_from_cart(current_cart) + + respond_to do |format| + if @order.save + Cart.destroy(session[:cart_id]) + session[:cart_id] = nil + OrderNotifier.received(@order).deliver + format.html { redirect_to store_url, notice: + I18n.t('.thanks') } + format.json { render json: @order, status: :created, + location: @order } + else + @cart = current_cart + format.html { render action: "new" } + format.json { render json: @order.errors, + status: :unprocessable_entity } + end + end + end + + # PUT /orders/1 + # PUT /orders/1.json + def update + @order = Order.find(params[:id]) + + respond_to do |format| + if @order.update_attributes(params[:order]) + format.html { redirect_to @order, notice: 'Order was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @order.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /orders/1 + # DELETE /orders/1.json + def destroy + @order = Order.find(params[:id]) + @order.destroy + + respond_to do |format| + format.html { redirect_to orders_url } + format.json { head :no_content } + end + end +end diff --git a/app/controllers/products_controller.rb b/app/controllers/products_controller.rb new file mode 100644 index 0000000..9c61702 --- /dev/null +++ b/app/controllers/products_controller.rb @@ -0,0 +1,107 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class ProductsController < ApplicationController + # GET /products + # GET /products.json + def index + @products = Product.all + + respond_to do |format| + format.html # index.html.erb + format.xml + format.json { render json: @products } + end + end + + # GET /products/1 + # GET /products/1.json + def show + @product = Product.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @product } + end + end + + # GET /products/new + # GET /products/new.json + def new + @product = Product.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @product } + end + end + + # GET /products/1/edit + def edit + @product = Product.find(params[:id]) + end + + # POST /products + # POST /products.json + def create + @product = Product.new(params[:product]) + + respond_to do |format| + if @product.save + format.html { redirect_to @product, + notice: 'Product was successfully created.' } + format.json { render json: @product, status: :created, + location: @product } + else + format.html { render action: "new" } + format.json { render json: @product.errors, + status: :unprocessable_entity } + end + end + end + + # PUT /products/1 + # PUT /products/1.json + def update + @product = Product.find(params[:id]) + + respond_to do |format| + if @product.update_attributes(params[:product]) + format.html { redirect_to @product, + notice: 'Product was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @product.errors, + status: :unprocessable_entity } + end + end + end + + # DELETE /products/1 + # DELETE /products/1.json + def destroy + @product = Product.find(params[:id]) + @product.destroy + + respond_to do |format| + format.html { redirect_to products_url } + format.json { head :no_content } + end + end + + def who_bought + @product = Product.find(params[:id]) + respond_to do |format| + format.html + format.xml + format.atom + format.json { render json: @product.to_json(include: :orders) } + end + end +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..64e05b0 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,28 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class SessionsController < ApplicationController + skip_before_filter :authorize + def new + end + + def create + user = User.find_by_name(params[:name]) + if user and user.authenticate(params[:password]) + session[:user_id] = user.id + redirect_to admin_url + else + redirect_to login_url, alert: "Invalid user/password combination" + end + end + + def destroy + session[:user_id] = nil + redirect_to store_url, notice: "Logged out" + end +end diff --git a/app/controllers/store_controller.rb b/app/controllers/store_controller.rb new file mode 100644 index 0000000..8f5050a --- /dev/null +++ b/app/controllers/store_controller.rb @@ -0,0 +1,23 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class StoreController < ApplicationController + skip_before_filter :authorize + def index + if params[:set_locale] + redirect_to store_path(locale: params[:set_locale]) + else + @products = Product.order(:title) + @cart = current_cart + end + + latest = Product.latest + fresh_when etag: latest, last_modified: latest.created_at.utc + expires_in 10.minutes, public: true + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..752dc27 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,101 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class UsersController < ApplicationController + # GET /users + # GET /users.json + def index + @users = User.order(:name) + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @users } + end + end + + # GET /users/1 + # GET /users/1.json + def show + @user = User.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @user } + end + end + + # GET /users/new + # GET /users/new.json + def new + @user = User.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @user } + end + end + + # GET /users/1/edit + def edit + @user = User.find(params[:id]) + end + + # POST /users + # POST /users.json + def create + @user = User.new(params[:user]) + + respond_to do |format| + if @user.save + format.html { redirect_to users_url, + notice: "User #{@user.name} was successfully created." } + format.json { render json: @user, + status: :created, location: @user } + else + format.html { render action: "new" } + format.json { render json: @user.errors, + status: :unprocessable_entity } + end + end + end + + # PUT /users/1 + # PUT /users/1.json + def update + @user = User.find(params[:id]) + + respond_to do |format| + if @user.update_attributes(params[:user]) + format.html { redirect_to users_url, + notice: "User #{@user.name} was successfully updated." } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @user.errors, + status: :unprocessable_entity } + end + end + end + + # DELETE /users/1 + # DELETE /users/1.json + def destroy + @user = User.find(params[:id]) + begin + @user.destroy + flash[:notice] = "User #{@user.name} deleted" + rescue Exception => e + flash[:notice] = e.message + end + + respond_to do |format| + format.html { redirect_to users_url } + format.json { head :no_content } + end + end +end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb new file mode 100644 index 0000000..621fc00 --- /dev/null +++ b/app/helpers/admin_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module AdminHelper +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..cb300b0 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,16 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module ApplicationHelper + def hidden_div_if(condition, attributes = {}, &block) + if condition + attributes["style"] = "display: none" + end + content_tag("div", attributes, &block) + end +end diff --git a/app/helpers/carts_helper.rb b/app/helpers/carts_helper.rb new file mode 100644 index 0000000..bced7a6 --- /dev/null +++ b/app/helpers/carts_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module CartsHelper +end diff --git a/app/helpers/line_items_helper.rb b/app/helpers/line_items_helper.rb new file mode 100644 index 0000000..467f502 --- /dev/null +++ b/app/helpers/line_items_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module LineItemsHelper +end diff --git a/app/helpers/orders_helper.rb b/app/helpers/orders_helper.rb new file mode 100644 index 0000000..d4baede --- /dev/null +++ b/app/helpers/orders_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module OrdersHelper +end diff --git a/app/helpers/products_helper.rb b/app/helpers/products_helper.rb new file mode 100644 index 0000000..2db412e --- /dev/null +++ b/app/helpers/products_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module ProductsHelper +end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 0000000..f48146e --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module SessionsHelper +end diff --git a/app/helpers/store_helper.rb b/app/helpers/store_helper.rb new file mode 100644 index 0000000..bcc3f6c --- /dev/null +++ b/app/helpers/store_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module StoreHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..0cc7da9 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,10 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +module UsersHelper +end diff --git a/app/mailers/.gitkeep b/app/mailers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/mailers/order_notifier.rb b/app/mailers/order_notifier.rb new file mode 100644 index 0000000..d93a7fe --- /dev/null +++ b/app/mailers/order_notifier.rb @@ -0,0 +1,33 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class OrderNotifier < ActionMailer::Base + default from: 'Sam Ruby ' + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.order_notifier.received.subject + # + def received(order) + @order = order + + mail to: order.email, subject: 'Pragmatic Store Order Confirmation' + end + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.order_notifier.shipped.subject + # + def shipped(order) + @order = order + + mail to: order.email, subject: 'Pragmatic Store Order Shipped' + end +end diff --git a/app/models/.gitkeep b/app/models/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/cart.rb b/app/models/cart.rb new file mode 100644 index 0000000..0f7d333 --- /dev/null +++ b/app/models/cart.rb @@ -0,0 +1,26 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class Cart < ActiveRecord::Base + has_many :line_items, dependent: :destroy + + def add_product(product_id) + current_item = line_items.find_by_product_id(product_id) + if current_item + current_item.quantity += 1 + else + current_item = line_items.build(product_id: product_id) + current_item.price = current_item.product.price + end + current_item + end + + def total_price + line_items.to_a.sum { |item| item.total_price } + end +end diff --git a/app/models/line_item.rb b/app/models/line_item.rb new file mode 100644 index 0000000..f652752 --- /dev/null +++ b/app/models/line_item.rb @@ -0,0 +1,17 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class LineItem < ActiveRecord::Base + belongs_to :order + belongs_to :product + belongs_to :cart + + def total_price + product.price * quantity + end +end diff --git a/app/models/order.rb b/app/models/order.rb new file mode 100644 index 0000000..1dde109 --- /dev/null +++ b/app/models/order.rb @@ -0,0 +1,21 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class Order < ActiveRecord::Base + PAYMENT_TYPES = [ "Check", "Credit card", "Purchase order" ] + has_many :line_items, dependent: :destroy + # ... + validates :name, :address, :email, presence: true + validates :pay_type, inclusion: PAYMENT_TYPES + def add_line_items_from_cart(cart) + cart.line_items.each do |item| + item.cart_id = nil + line_items << item + end + end +end diff --git a/app/models/product.rb b/app/models/product.rb new file mode 100644 index 0000000..7934a78 --- /dev/null +++ b/app/models/product.rb @@ -0,0 +1,42 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class Product < ActiveRecord::Base + has_many :line_items + has_many :orders, through: :line_items + #... + + before_destroy :ensure_not_referenced_by_any_line_item + + validates :title, :description, :image_url, presence: true + validates :price, numericality: {greater_than_or_equal_to: 0.01} +# + validates :title, uniqueness: true + validates :image_url, allow_blank: true, format: { + with: %r{\.(gif|jpg|png)$}i, + message: 'must be a URL for GIF, JPG or PNG image.' + } + validates :title, length: {minimum: 10} + def self.latest + Product.order('updated_at desc').limit(1).first + end + + + + private + + # ensure that there are no line items referencing this product + def ensure_not_referenced_by_any_line_item + if line_items.empty? + return true + else + errors.add(:base, 'Line Items present') + return false + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..d05c68f --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,21 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class User < ActiveRecord::Base + validates :name, presence: true, uniqueness: true + has_secure_password + + after_destroy :ensure_an_admin_remains + + private + def ensure_an_admin_remains + if User.count.zero? + raise "Can't delete last user" + end + end +end diff --git a/app/store.rb b/app/store.rb new file mode 100644 index 0000000..f415db3 --- /dev/null +++ b/app/store.rb @@ -0,0 +1,33 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class StoreApp + def call(env) + x = Builder::XmlMarkup.new :indent=>2 + + x.declare! :DOCTYPE, :html + x.html do + x.head do + x.title 'Pragmatic Bookshelf' + end + x.body do + x.h1 'Pragmatic Bookshelf' + + Product.all.each do |product| + x.h2 product.title + x << " #{product.description}\n" + x.p product.price + end + end + end + + response = Rack::Response.new(x.target!) + response['Content-Type'] = 'text/html' + response.finish + end +end diff --git a/app/views/admin/index.html.erb b/app/views/admin/index.html.erb new file mode 100644 index 0000000..384754e --- /dev/null +++ b/app/views/admin/index.html.erb @@ -0,0 +1,4 @@ +

Welcome

+ +It's <%= Time.now %> +We have <%= pluralize(@total_orders, "order") %>. diff --git a/app/views/carts/_cart.html.erb b/app/views/carts/_cart.html.erb new file mode 100644 index 0000000..3a72135 --- /dev/null +++ b/app/views/carts/_cart.html.erb @@ -0,0 +1,20 @@ + +
<%= t('.title') %>
+ + + <%= render(cart.line_items) %> + + + + + + +
Total<%= number_to_currency(cart.total_price) %>
+ + +<%= button_to t('.checkout'), new_order_path, method: :get %> + + +<%= button_to t('.empty'), cart, method: :delete, +# END_HIGHLIGHT + confirm: 'Are you sure?' %> diff --git a/app/views/carts/_form.html.erb b/app/views/carts/_form.html.erb new file mode 100644 index 0000000..6a781a9 --- /dev/null +++ b/app/views/carts/_form.html.erb @@ -0,0 +1,17 @@ +<%= form_for(@cart) do |f| %> + <% if @cart.errors.any? %> +
+

<%= pluralize(@cart.errors.count, "error") %> prohibited this cart from being saved:

+ +
    + <% @cart.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= f.submit %> +
+<% end %> diff --git a/app/views/carts/edit.html.erb b/app/views/carts/edit.html.erb new file mode 100644 index 0000000..52ffef7 --- /dev/null +++ b/app/views/carts/edit.html.erb @@ -0,0 +1,6 @@ +

Editing cart

+ +<%= render 'form' %> + +<%= link_to 'Show', @cart %> | +<%= link_to 'Back', carts_path %> diff --git a/app/views/carts/index.html.erb b/app/views/carts/index.html.erb new file mode 100644 index 0000000..abe66b6 --- /dev/null +++ b/app/views/carts/index.html.erb @@ -0,0 +1,21 @@ +

Listing carts

+ + + + + + + + +<% @carts.each do |cart| %> + + + + + +<% end %> +
<%= link_to 'Show', cart %><%= link_to 'Edit', edit_cart_path(cart) %><%= link_to 'Destroy', cart, confirm: 'Are you sure?', method: :delete %>
+ +
+ +<%= link_to 'New Cart', new_cart_path %> diff --git a/app/views/carts/new.html.erb b/app/views/carts/new.html.erb new file mode 100644 index 0000000..cbef49c --- /dev/null +++ b/app/views/carts/new.html.erb @@ -0,0 +1,5 @@ +

New cart

+ +<%= render 'form' %> + +<%= link_to 'Back', carts_path %> diff --git a/app/views/carts/show.html.erb b/app/views/carts/show.html.erb new file mode 100644 index 0000000..8c82f6d --- /dev/null +++ b/app/views/carts/show.html.erb @@ -0,0 +1,7 @@ +<% if notice %> +

<%= notice %>

+<% end %> + + +<%= render @cart %> + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000..024b55b --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,58 @@ + + + + + Pragprog Books Online Store + <%= stylesheet_link_tag "application" %> + <%= javascript_include_tag "application" %> + <%= csrf_meta_tag %> + + + + + + +
+
+ + <% if @cart %> + <%= hidden_div_if(@cart.line_items.empty?, id: 'cart') do %> + <%= render @cart %> + <% end %> + <% end %> + + + + + <% if session[:user_id] %> +
    +
  • <%= link_to 'Orders', orders_path %>
  • +
  • <%= link_to 'Products', products_path %>
  • +
  • <%= link_to 'Users', users_path %>
  • +
+ <%= button_to 'Logout', logout_path, method: :delete %> + <% end %> +
+
+ <%= yield %> +
+
+ + diff --git a/app/views/line_items/_form.html.erb b/app/views/line_items/_form.html.erb new file mode 100644 index 0000000..67c6a17 --- /dev/null +++ b/app/views/line_items/_form.html.erb @@ -0,0 +1,25 @@ +<%= form_for(@line_item) do |f| %> + <% if @line_item.errors.any? %> +
+

<%= pluralize(@line_item.errors.count, "error") %> prohibited this line_item from being saved:

+ +
    + <% @line_item.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= f.label :product_id %>
+ <%= f.number_field :product_id %> +
+
+ <%= f.label :cart_id %>
+ <%= f.number_field :cart_id %> +
+
+ <%= f.submit %> +
+<% end %> diff --git a/app/views/line_items/_line_item.html.erb b/app/views/line_items/_line_item.html.erb new file mode 100644 index 0000000..f1c9c83 --- /dev/null +++ b/app/views/line_items/_line_item.html.erb @@ -0,0 +1,9 @@ +<% if line_item == @current_item %> + +<% else %> + +<% end %> + <%= line_item.quantity %>× + <%= line_item.product.title %> + <%= number_to_currency(line_item.total_price) %> + diff --git a/app/views/line_items/_line_item.text.erb b/app/views/line_items/_line_item.text.erb new file mode 100644 index 0000000..0806cab --- /dev/null +++ b/app/views/line_items/_line_item.text.erb @@ -0,0 +1,3 @@ +<%= sprintf("%2d x %s", + line_item.quantity, + truncate(line_item.product.title, length: 50)) %> diff --git a/app/views/line_items/create.js.erb b/app/views/line_items/create.js.erb new file mode 100644 index 0000000..1c06367 --- /dev/null +++ b/app/views/line_items/create.js.erb @@ -0,0 +1,10 @@ +//#START_HIGHLIGHT +$("#notice").hide(); + +//#END_HIGHLIGHT +if ($('#cart tr').length == 1) { $('#cart').show('blind', 1000); } + +$('#cart').html("<%=j render @cart %>"); + +$('#current_item').css({'background-color':'#88ff88'}). + animate({'background-color':'#114411'}, 1000); diff --git a/app/views/line_items/edit.html.erb b/app/views/line_items/edit.html.erb new file mode 100644 index 0000000..0b50068 --- /dev/null +++ b/app/views/line_items/edit.html.erb @@ -0,0 +1,6 @@ +

Editing line_item

+ +<%= render 'form' %> + +<%= link_to 'Show', @line_item %> | +<%= link_to 'Back', line_items_path %> diff --git a/app/views/line_items/index.html.erb b/app/views/line_items/index.html.erb new file mode 100644 index 0000000..37938f0 --- /dev/null +++ b/app/views/line_items/index.html.erb @@ -0,0 +1,25 @@ +

Listing line_items

+ + + + + + + + + + +<% @line_items.each do |line_item| %> + + + + + + + +<% end %> +
ProductCart
<%= line_item.product_id %><%= line_item.cart_id %><%= link_to 'Show', line_item %><%= link_to 'Edit', edit_line_item_path(line_item) %><%= link_to 'Destroy', line_item, confirm: 'Are you sure?', method: :delete %>
+ +
+ +<%= link_to 'New Line item', new_line_item_path %> diff --git a/app/views/line_items/new.html.erb b/app/views/line_items/new.html.erb new file mode 100644 index 0000000..32b6dd9 --- /dev/null +++ b/app/views/line_items/new.html.erb @@ -0,0 +1,5 @@ +

New line_item

+ +<%= render 'form' %> + +<%= link_to 'Back', line_items_path %> diff --git a/app/views/line_items/show.html.erb b/app/views/line_items/show.html.erb new file mode 100644 index 0000000..f5de102 --- /dev/null +++ b/app/views/line_items/show.html.erb @@ -0,0 +1,15 @@ +

<%= notice %>

+ +

+ Product: + <%= @line_item.product_id %> +

+ +

+ Cart: + <%= @line_item.cart_id %> +

+ + +<%= link_to 'Edit', edit_line_item_path(@line_item) %> | +<%= link_to 'Back', line_items_path %> diff --git a/app/views/order_notifier/received.text.erb b/app/views/order_notifier/received.text.erb new file mode 100644 index 0000000..8d5477a --- /dev/null +++ b/app/views/order_notifier/received.text.erb @@ -0,0 +1,9 @@ +Dear <%= @order.name %> + +Thank you for your recent order from The Pragmatic Store. + +You ordered the following items: + +<%= render @order.line_items %> + +We'll send you a separate e-mail when your order ships. diff --git a/app/views/order_notifier/shipped.html.erb b/app/views/order_notifier/shipped.html.erb new file mode 100644 index 0000000..a9d844d --- /dev/null +++ b/app/views/order_notifier/shipped.html.erb @@ -0,0 +1,9 @@ +

Pragmatic Order Shipped

+

+ This is just to let you know that we've shipped your recent order: +

+ + + +<%= render @order.line_items %> +
QtyDescription
diff --git a/app/views/order_notifier/shipped.text.erb b/app/views/order_notifier/shipped.text.erb new file mode 100644 index 0000000..73b8052 --- /dev/null +++ b/app/views/order_notifier/shipped.text.erb @@ -0,0 +1,3 @@ +OrderNotifier#shipped + +<%= @greeting %>, find me in app/views/app/views/order_notifier/shipped.text.erb diff --git a/app/views/orders/_form.html.erb b/app/views/orders/_form.html.erb new file mode 100644 index 0000000..529bdcb --- /dev/null +++ b/app/views/orders/_form.html.erb @@ -0,0 +1,49 @@ + +<%= form_for(@order) do |f| %> + <% if @order.errors.any? %> +
+ +

<%=raw t('errors.template.header', count: @order.errors.count, + model: t('activerecord.models.order')) %>.

+

<%= t('errors.template.body') %>

+ + +
    + <% @order.errors.full_messages.each do |msg| %> + +
  • <%=raw msg %>
  • + + <% end %> +
+
+ <% end %> + + + +
+ <%= f.label :name %>
+ <%= f.text_field :name, size: 40 %> +
+
+ + <%= f.label :address, t('.address_html') %>
+ + <%= f.text_area :address, rows: 3, cols: 40 %> +
+
+ <%= f.label :email %>
+ <%= f.email_field :email, size: 40 %> +
+
+ <%= f.label :pay_type %>
+ <%= f.select :pay_type, Order::PAYMENT_TYPES, +#START_HIGHLIGHT + prompt: t('.pay_prompt_html') %> + +
+
+ + <%= f.submit t('.submit') %> + +
+<% end %> diff --git a/app/views/orders/edit.html.erb b/app/views/orders/edit.html.erb new file mode 100644 index 0000000..b07ade6 --- /dev/null +++ b/app/views/orders/edit.html.erb @@ -0,0 +1,6 @@ +

Editing order

+ +<%= render 'form' %> + +<%= link_to 'Show', @order %> | +<%= link_to 'Back', orders_path %> diff --git a/app/views/orders/index.html.erb b/app/views/orders/index.html.erb new file mode 100644 index 0000000..316be25 --- /dev/null +++ b/app/views/orders/index.html.erb @@ -0,0 +1,33 @@ +

Listing orders

+ + + + + + + + + + + + +<% @orders.each do |order| %> + + + + + + + + + +<% end %> +
NameAddressEmailPay type
<%= order.name %><%= order.address %><%= order.email %><%= order.pay_type %><%= link_to 'Show', order %><%= link_to 'Edit', edit_order_path(order) %><%= link_to 'Destroy', order, confirm: 'Are you sure?', + method: :delete %>
+ +
+ +<%= link_to 'New Order', new_order_path %> + +

<%= will_paginate @orders %>

+ diff --git a/app/views/orders/new.html.erb b/app/views/orders/new.html.erb new file mode 100644 index 0000000..237f663 --- /dev/null +++ b/app/views/orders/new.html.erb @@ -0,0 +1,8 @@ +
+
+ + <%= t('.legend') %> + + <%= render 'form' %> +
+
diff --git a/app/views/orders/show.html.erb b/app/views/orders/show.html.erb new file mode 100644 index 0000000..1828f28 --- /dev/null +++ b/app/views/orders/show.html.erb @@ -0,0 +1,25 @@ +

<%= notice %>

+ +

+ Name: + <%= @order.name %> +

+ +

+ Address: + <%= @order.address %> +

+ +

+ Email: + <%= @order.email %> +

+ +

+ Pay type: + <%= @order.pay_type %> +

+ + +<%= link_to 'Edit', edit_order_path(@order) %> | +<%= link_to 'Back', orders_path %> diff --git a/app/views/products/_form.html.erb b/app/views/products/_form.html.erb new file mode 100644 index 0000000..926d9b7 --- /dev/null +++ b/app/views/products/_form.html.erb @@ -0,0 +1,36 @@ +<%= form_for(@product) do |f| %> + <% if @product.errors.any? %> +
+

<%= pluralize(@product.errors.count, "error") %> + prohibited this product from being saved:

+ +
    + <% @product.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= f.label :title %>
+ <%= f.text_field :title %> +
+
+ <%= f.label :description %>
+ + <%= f.text_area :description, rows: 6 %> + +
+
+ <%= f.label :image_url %>
+ <%= f.text_field :image_url %> +
+
+ <%= f.label :price %>
+ <%= f.text_field :price %> +
+
+ <%= f.submit %> +
+<% end %> diff --git a/app/views/products/edit.html.erb b/app/views/products/edit.html.erb new file mode 100644 index 0000000..39f7f4f --- /dev/null +++ b/app/views/products/edit.html.erb @@ -0,0 +1,6 @@ +

Editing product

+ +<%= render 'form' %> + +<%= link_to 'Show', @product %> | +<%= link_to 'Back', products_path %> diff --git a/app/views/products/index.html.erb b/app/views/products/index.html.erb new file mode 100644 index 0000000..8fdceab --- /dev/null +++ b/app/views/products/index.html.erb @@ -0,0 +1,32 @@ +

Listing products

+ + +<% @products.each do |product| %> + + + + + + + + +<% end %> +
+ <%= image_tag(product.image_url, class: 'list_image') %> + +
+
<%= product.title %>
+
<%= truncate(strip_tags(product.description), + length: 80) %>
+
+
+ <%= link_to 'Show', product %>
+ <%= link_to 'Edit', edit_product_path(product) %>
+ <%= link_to 'Destroy', product, + confirm: 'Are you sure?', + method: :delete %> +
+ +
+ +<%= link_to 'New product', new_product_path %> diff --git a/app/views/products/index.xml.builder b/app/views/products/index.xml.builder new file mode 100644 index 0000000..424bb75 --- /dev/null +++ b/app/views/products/index.xml.builder @@ -0,0 +1,11 @@ +xml.div(class: "productlist") do + + xml.timestamp(Time.now) + + @products.each do |product| + xml.product do + xml.productname(product.title) + xml.price(product.price, currency: "USD") + end + end +end diff --git a/app/views/products/new.html.erb b/app/views/products/new.html.erb new file mode 100644 index 0000000..e5e0037 --- /dev/null +++ b/app/views/products/new.html.erb @@ -0,0 +1,5 @@ +

New product

+ +<%= render 'form' %> + +<%= link_to 'Back', products_path %> diff --git a/app/views/products/show.html.erb b/app/views/products/show.html.erb new file mode 100644 index 0000000..aed4bc3 --- /dev/null +++ b/app/views/products/show.html.erb @@ -0,0 +1,25 @@ +

<%= notice %>

+ +

+ Title: + <%= @product.title %> +

+ +

+ Description: + <%= @product.description %> +

+ +

+ Image url: + <%= @product.image_url %> +

+ +

+ Price: + <%= @product.price %> +

+ + +<%= link_to 'Edit', edit_product_path(@product) %> | +<%= link_to 'Back', products_path %> diff --git a/app/views/products/who_bought.atom.builder b/app/views/products/who_bought.atom.builder new file mode 100644 index 0000000..efdd44a --- /dev/null +++ b/app/views/products/who_bought.atom.builder @@ -0,0 +1,41 @@ +atom_feed do |feed| + feed.title "Who bought #{@product.title}" + + latest_order = @product.orders.sort_by(&:updated_at).last + feed.updated( latest_order && latest_order.updated_at ) + + @product.orders.each do |order| + feed.entry(order) do |entry| + entry.title "Order #{order.id}" + entry.summary type: 'xhtml' do |xhtml| + xhtml.p "Shipped to #{order.address}" + + xhtml.table do + xhtml.tr do + xhtml.th 'Product' + xhtml.th 'Quantity' + xhtml.th 'Total Price' + end + order.line_items.each do |item| + xhtml.tr do + xhtml.td item.product.title + xhtml.td item.quantity + xhtml.td number_to_currency item.total_price + end + end + xhtml.tr do + xhtml.th 'total', colspan: 2 + xhtml.th number_to_currency \ + order.line_items.map(&:total_price).sum + end + end + + xhtml.p "Paid by #{order.pay_type}" + end + entry.author do |author| + author.name order.name + author.email order.email + end + end + end +end diff --git a/app/views/products/who_bought.html.erb b/app/views/products/who_bought.html.erb new file mode 100644 index 0000000..82d9a7f --- /dev/null +++ b/app/views/products/who_bought.html.erb @@ -0,0 +1,9 @@ +

People Who Bought <%= @product.title %>

+ +
    + <% for order in @product.orders %> +
  • + <%= mail_to order.email, order.name %> +
  • + <% end %> +
diff --git a/app/views/products/who_bought.xml.builder b/app/views/products/who_bought.xml.builder new file mode 100644 index 0000000..6eeda2e --- /dev/null +++ b/app/views/products/who_bought.xml.builder @@ -0,0 +1,8 @@ +xml.order_list(:for_product => @product.title) do + for o in @product.orders + xml.order do + xml.name(o.name) + xml.email(o.email) + end + end +end diff --git a/app/views/sessions/create.html.erb b/app/views/sessions/create.html.erb new file mode 100644 index 0000000..c251174 --- /dev/null +++ b/app/views/sessions/create.html.erb @@ -0,0 +1,2 @@ +

Sessions#create

+

Find me in app/views/sessions/create.html.erb

diff --git a/app/views/sessions/destroy.html.erb b/app/views/sessions/destroy.html.erb new file mode 100644 index 0000000..d75237d --- /dev/null +++ b/app/views/sessions/destroy.html.erb @@ -0,0 +1,2 @@ +

Sessions#destroy

+

Find me in app/views/sessions/destroy.html.erb

diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 0000000..30d059f --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,25 @@ +
+ <% if flash[:alert] %> +

<%= flash[:alert] %>

+ <% end %> + + <%= form_tag do %> +
+ Please Log In + +
+ <%= label_tag :name, 'Name:' %> + <%= text_field_tag :name, params[:name] %> +
+ +
+ <%= label_tag :password, 'Password:' %> + <%= password_field_tag :password, params[:password] %> +
+ +
+ <%= submit_tag "Login" %> +
+
+ <% end %> +
diff --git a/app/views/store/index.html.haml b/app/views/store/index.html.haml new file mode 100644 index 0000000..f47d004 --- /dev/null +++ b/app/views/store/index.html.haml @@ -0,0 +1,14 @@ +- if notice + %p#notice= notice + +%h1= t('.title_html') + +- @products.each do |product| + .entry + = image_tag(product.image_url) + %h3= product.title + = sanitize(product.description) + .price_line + %span.price= number_to_currency(product.price) + = button_to t('.add_html'), line_items_path(product_id: product), + remote: true diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb new file mode 100644 index 0000000..1de787b --- /dev/null +++ b/app/views/users/_form.html.erb @@ -0,0 +1,41 @@ +
+ +<%= form_for @user do |f| %> + <% if @user.errors.any? %> +
+

<%= pluralize(@user.errors.count, "error") %> + prohibited this user from being saved:

+
    + <% @user.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+
+ <% end %> + +
+ Enter User Details + +
+ <%= f.label :name %>: + <%= f.text_field :name, size: 40 %> +
+ +
+ <%= f.label :password, 'Password' %>: + <%= f.password_field :password, size: 40 %> +
+ +
+ <%= f.label :password_confirmation, 'Confirm' %>: + <%= f.password_field :password_confirmation, size: 40 %> +
+ +
+ <%= f.submit %> +
+ +
+<% end %> + +
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100644 index 0000000..99bd4cc --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,6 @@ +

Editing user

+ +<%= render 'form' %> + +<%= link_to 'Show', @user %> | +<%= link_to 'Back', users_path %> diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb new file mode 100644 index 0000000..9b4cff8 --- /dev/null +++ b/app/views/users/index.html.erb @@ -0,0 +1,29 @@ +

Listing users

+ + <% if notice %> +

<%= notice %>

+ <% end %> + + + + + + + + + + +<% @users.each do |user| %> + + + + + + +<% end %> +
Name
<%= user.name %><%= link_to 'Show', user %><%= link_to 'Edit', edit_user_path(user) %><%= link_to 'Destroy', user, confirm: 'Are you sure?', + method: :delete %>
+ +
+ +<%= link_to 'New User', new_user_path %> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 0000000..efc0404 --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,5 @@ +

New user

+ +<%= render 'form' %> + +<%= link_to 'Back', users_path %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100644 index 0000000..20e6390 --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1,15 @@ +

<%= notice %>

+ +

+ Name: + <%= @user.name %> +

+ +

+ Password digest: + <%= @user.password_digest %> +

+ + +<%= link_to 'Edit', edit_user_path(@user) %> | +<%= link_to 'Back', users_path %> diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..d5d8bb5 --- /dev/null +++ b/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Depot::Application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..8f09ecb --- /dev/null +++ b/config/application.rb @@ -0,0 +1,67 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require File.expand_path('../boot', __FILE__) + +require 'rails/all' + +if defined?(Bundler) + # If you precompile assets before deploying to production, use this line + Bundler.require(*Rails.groups(:assets => %w(development test))) + # If you want your assets lazily compiled in production, use this line + # Bundler.require(:default, :assets, Rails.env) +end + +module Depot + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Custom directories with classes and modules you want to be autoloadable. + # config.autoload_paths += %W(#{config.root}/extras) + + # Only load the plugins named here, in the order given (default is alphabetical). + # :all can be used as a placeholder for all plugins not explicitly named. + # config.plugins = [ :exception_notification, :ssl_requirement, :all ] + + # Activate observers that should always be running. + # config.active_record.observers = :cacher, :garbage_collector, :forum_observer + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # Configure the default encoding used in templates for Ruby 1.9. + config.encoding = "utf-8" + + # Configure sensitive parameters which will be filtered from the log file. + config.filter_parameters += [:password] + + # Use SQL instead of Active Record's schema dumper when creating the database. + # This is necessary if your schema can't be completely dumped by the schema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format = :sql + + # Enforce whitelist mode for mass assignment. + # This will create an empty whitelist of attributes available for mass-assignment for all models + # in your app. As such, your models will need to explicitly whitelist or blacklist accessible + # parameters by using an attr_accessible or attr_protected declaration. + # config.active_record.whitelist_attributes = true + + # Enable the asset pipeline + config.assets.enabled = true + + # Version of your assets, change this if you want to expire all your assets + config.assets.version = '1.0' + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..d85a5de --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,14 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'rubygems' + +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..dd3d642 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,31 @@ +# SQLite version 3.x +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem 'sqlite3' +development: + adapter: sqlite3 + database: db/development.sqlite3 + pool: 5 + timeout: 5000 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + adapter: sqlite3 + database: db/test.sqlite3 + pool: 5 + timeout: 5000 + +#START:production +production: + adapter: mysql2 + encoding: utf8 + reconnect: false + database: depot_production + pool: 5 + username: username + password: password + host: localhost +#END:production diff --git a/config/deploy.rb b/config/deploy.rb new file mode 100644 index 0000000..673bdcf --- /dev/null +++ b/config/deploy.rb @@ -0,0 +1,65 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# be sure to change these +set :user, 'rubys' +set :domain, 'depot.pragprog.com' +set :application, 'depot' + +# adjust if you are using RVM, remove if you are not +$:.unshift(File.expand_path('./lib', ENV['rvm_path'])) +require "rvm/capistrano" +set :rvm_ruby_string, '1.9.2' +set :rvm_type, :user + +# file paths +set :repository, "#{user}@#{domain}:git/#{application}.git" +set :deploy_to, "/home/#{user}/#{domain}" + +# distribute your applications across servers (the instructions below put them +# all on the same server, defined above as 'domain', adjust as necessary) +role :app, domain +role :web, domain +role :db, domain, :primary => true + +# you might need to set this if you aren't seeing password prompts +# default_run_options[:pty] = true + +# As Capistrano executes in a non-interactive mode and therefore doesn't cause +# any of your shell profile scripts to be run, the following might be needed +# if (for example) you have locally installed gems or applications. Note: +# this needs to contain the full values for the variables set, not simply +# the deltas. +# default_environment['PATH']=':/usr/local/bin:/usr/bin:/bin' +# default_environment['GEM_PATH']=':/usr/lib/ruby/gems/1.8' + +# miscellaneous options +set :deploy_via, :remote_cache +set :scm, 'git' +set :branch, 'master' +set :scm_verbose, true +set :use_sudo, false +set :rails_env, :production + +namespace :deploy do + desc "cause Passenger to initiate a restart" + task :restart do + run "touch #{current_path}/tmp/restart.txt" + end + + desc "reload the database with seed data" + task :seed do + run "cd #{current_path}; rake db:seed RAILS_ENV=#{rails_env}" + end +end + +after "deploy:update_code", :bundle_install +desc "install the necessary prerequisites" +task :bundle_install, :roles => :app do + run "cd #{release_path} && bundle install" +end diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..21ce32a --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,13 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# Load the rails application +require File.expand_path('../application', __FILE__) + +# Initialize the rails application +Depot::Application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..a9e6fba --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,60 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +Depot::Application.configure do + # Settings specified here will take precedence over those in config/application.rb + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Log error messages when you accidentally call methods on nil. + config.whiny_nils = true + + # Show full error reports and disable caching + config.consider_all_requests_local = true + config.action_controller.perform_caching = true + + # Don't care if the mailer can't send + config.action_mailer.raise_delivery_errors = false + + # Don't actually send emails + config.action_mailer.delivery_method = :test + # + # Alternate configuration example, using gmail: + # config.action_mailer.delivery_method = :smtp + # config.action_mailer.smtp_settings = { + # address: "smtp.gmail.com", + # port: 587, + # domain: "domain.of.sender.net", + # authentication: "plain", + # user_name: "dave", + # password: "secret", + # enable_starttls_auto: true + # } + + # Print deprecation notices to the Rails logger + config.active_support.deprecation = :log + + # Only use best-standards-support built into browsers + config.action_dispatch.best_standards_support = :builtin + + # Raise exception on mass assignment protection for Active Record models + config.active_record.mass_assignment_sanitizer = :strict + + # Log the query plan for queries taking more than this (works + # with SQLite, MySQL, and PostgreSQL) + config.active_record.auto_explain_threshold_in_seconds = 0.5 + + # Do not compress assets + config.assets.compress = false + + # Expands the lines which load the assets + config.assets.debug = true +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..8d42451 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,78 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +Depot::Application.configure do + # Settings specified here will take precedence over those in config/application.rb + + # Code is not reloaded between requests + config.cache_classes = true + + # Full error reports are disabled and caching is turned on + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Disable Rails's static asset server (Apache or nginx will already do this) + config.serve_static_assets = false + + # Compress JavaScripts and CSS + config.assets.compress = true + + # Don't fallback to assets pipeline if a precompiled asset is missed + config.assets.compile = false + + # Generate digests for assets URLs + config.assets.digest = true + + # Defaults to Rails.root.join("public/assets") + # config.assets.manifest = YOUR_PATH + + # Specifies the header that your server uses for sending files + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # See everything in the log (default is :info) + # config.log_level = :debug + + # Prepend all log lines with the following tags + # config.log_tags = [ :subdomain, :uuid ] + + # Use a different logger for distributed setups + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production + # config.cache_store = :mem_cache_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server + # config.action_controller.asset_host = "http://assets.example.com" + + # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) + # config.assets.precompile += %w( search.js ) + + # Disable delivery errors, bad email addresses will be ignored + # config.action_mailer.raise_delivery_errors = false + + # Enable threaded mode + # config.threadsafe! + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation can not be found) + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners + config.active_support.deprecation = :notify + + # Log the query plan for queries taking more than this (works + # with SQLite, MySQL, and PostgreSQL) + # config.active_record.auto_explain_threshold_in_seconds = 0.5 + + require 'active_support/core_ext/numeric/bytes' + config.logger = Logger.new(paths['log'].first, 2, 10.kilobytes) +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..31ef762 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,45 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +Depot::Application.configure do + # Settings specified here will take precedence over those in config/application.rb + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Configure static asset server for tests with Cache-Control for performance + config.serve_static_assets = true + config.static_cache_control = "public, max-age=3600" + + # Log error messages when you accidentally call methods on nil + config.whiny_nils = true + + # Show full error reports and disable caching + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Raise exception on mass assignment protection for Active Record models + config.active_record.mass_assignment_sanitizer = :strict + + # Print deprecation notices to the stderr + config.active_support.deprecation = :stderr +end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..cb8a4f8 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,15 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb new file mode 100644 index 0000000..9bde132 --- /dev/null +++ b/config/initializers/i18n.rb @@ -0,0 +1,15 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +#encoding: utf-8 +I18n.default_locale = :en + +LANGUAGES = [ + ['English', 'en'], + ["Español".html_safe, 'es'] +] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..5f76653 --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,27 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format +# (all these examples are active by default): +# ActiveSupport::Inflector.inflections do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end +# +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections do |inflect| +# inflect.acronym 'RESTful' +# end + +ActiveSupport::Inflector.inflections do |inflect| + inflect.irregular 'tax', 'taxes' +end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 0000000..8db8ab0 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,13 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf +# Mime::Type.register_alias "text/html", :iphone diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb new file mode 100644 index 0000000..d60aa0a --- /dev/null +++ b/config/initializers/secret_token.rb @@ -0,0 +1,15 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# Be sure to restart your server when you modify this file. + +# Your secret key for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +Depot::Application.config.secret_token = '06f84ea4c18d4d722a394e9bbf8367a4050bfd680da0b11ffd02a514935d24d93f650f4e64fea0a9eddb5056eab513f5760501a20769e0587a2dd5f0d623456b' diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 0000000..6543b24 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,16 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# Be sure to restart your server when you modify this file. + +Depot::Application.config.session_store :cookie_store, key: '_depot_session' + +# Use the database for sessions instead of the cookie-based default, +# which shouldn't be used to store highly confidential information +# (create the session table with "rails generate session_migration") +# Depot::Application.config.session_store :active_record_store diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..b6cfbeb --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,22 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# Be sure to restart your server when you modify this file. +# +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# Disable root element in JSON by default. +ActiveSupport.on_load(:active_record) do + self.include_root_in_json = false +end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..a163757 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,73 @@ +#START:layout +#START:main +#START:cart +#START:currency +#START:checkout +#START:flash +en: + +#END:cart +#END:checkout +#END:flash +#END:main +#END:layout + number: + currency: + format: + unit: "$" + precision: 2 + separator: "." + delimiter: "," + format: "%u%n" +#END:currency + +#START:errors + errors: + template: + body: "There were problems with the following fields:" + header: + one: "1 error prohibited this %{model} from being saved" + other: "%{count} errors prohibited this %{model} from being saved" +#END:errors + +#START:layout + layouts: + application: + title: "Pragmatic Bookshelf" + home: "Home" + questions: "Questions" + news: "News" + contact: "Contact" +#END:layout + +#START:cart + carts: + cart: + title: "Your Cart" + empty: "Empty cart" + checkout: "Checkout" +#END:cart + +#START:main + store: + index: + title_html: "Your Pragmatic Catalog" + add_html: "Add to Cart" +#END:main + +#START:checkout + orders: + new: + legend: "Please Enter Your Details" + form: + name: "Name" + address_html: "Address" + email: "E-mail" + pay_type: "Pay with" + pay_prompt_html: "Select a payment method" + submit: "Place Order" +#END:checkout + +#START:flash + thanks: "Thank you for your order" +#END:flash diff --git a/config/locales/es.yml b/config/locales/es.yml new file mode 100644 index 0000000..7e636b5 --- /dev/null +++ b/config/locales/es.yml @@ -0,0 +1,94 @@ +#START:layout +#START:main +#START:cart +#START:currency +#START:checkout +#START:errors +#START:model +#START:flash +es: + +#END:cart +#END:flash +#END:model +#END:errors +#END:checkout +#END:main +#END:layout + number: + currency: + format: + unit: "$US" + precision: 2 + separator: "," + delimiter: "." + format: "%n %u" +#END:currency + +#START:model +#START:errors + activerecord: +#END:errors + models: + order: "pedido" + attributes: + order: + address: "Dirección" + name: "Nombre" + email: "E-mail" + pay_type: "Forma de pago" +#END:model +#START:errors + errors: + messages: + inclusion: "no está incluido en la lista" + blank: "no puede quedar en blanco" + errors: + template: + body: "Hay problemas con los siguientes campos:" + header: + one: "1 error ha impedido que este %{model} se guarde" + other: "%{count} errores han impedido que este %{model} se guarde" +#END:errors + +#START:layout + layouts: + application: + title: "Publicaciones de Pragmatic" + home: "Inicio" + questions: "Preguntas" + news: "Noticias" + contact: "Contacto" +#END:layout + +#START:cart + carts: + cart: + title: "Carrito de la Compra" + empty: "Vaciar Carrito" + checkout: "Comprar" +#END:cart + +#START:main + store: + index: + title_html: "Su Catálogo de Pragmatic" + add_html: "Añadir al Carrito" +#END:main + +#START:checkout + orders: + new: + legend: "Por favor, introduzca sus datos" + form: + name: "Nombre" + address_html: "Dirección" + email: "E-mail" + pay_type: "Forma de pago" + pay_prompt_html: "Seleccione un método de pago" + submit: "Realizar Pedido" +#END:checkout + +#START:flash + thanks: "Gracias por su pedido" +#END:flash diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..3bf7b09 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,31 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require './app/store' +Depot::Application.routes.draw do + match 'store' => StoreApp.new + get 'admin' => 'admin#index' + controller :sessions do + get 'login' => :new + post 'login' => :create + delete 'logout' => :destroy + end + scope '(:locale)' do + resources :users + resources :orders do + resources :line_items + end + + resources :line_items + resources :carts + resources :products do + get :who_bought, on: :member + end + root to: 'store#index', as: 'store' + end +end diff --git a/db/backup/production.backup b/db/backup/production.backup new file mode 100644 index 0000000..1c82d76 --- /dev/null +++ b/db/backup/production.backup @@ -0,0 +1,3 @@ +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +COMMIT; diff --git a/db/migrate/20110711000001_create_products.rb b/db/migrate/20110711000001_create_products.rb new file mode 100644 index 0000000..9c61f54 --- /dev/null +++ b/db/migrate/20110711000001_create_products.rb @@ -0,0 +1,20 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class CreateProducts < ActiveRecord::Migration + def change + create_table :products do |t| + t.string :title + t.text :description + t.string :image_url + t.decimal :price, precision: 8, scale: 2 + + t.timestamps + end + end +end diff --git a/db/migrate/20110711000002_create_carts.rb b/db/migrate/20110711000002_create_carts.rb new file mode 100644 index 0000000..df705ab --- /dev/null +++ b/db/migrate/20110711000002_create_carts.rb @@ -0,0 +1,16 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class CreateCarts < ActiveRecord::Migration + def change + create_table :carts do |t| + + t.timestamps + end + end +end diff --git a/db/migrate/20110711000003_create_line_items.rb b/db/migrate/20110711000003_create_line_items.rb new file mode 100644 index 0000000..2ab10ff --- /dev/null +++ b/db/migrate/20110711000003_create_line_items.rb @@ -0,0 +1,18 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class CreateLineItems < ActiveRecord::Migration + def change + create_table :line_items do |t| + t.integer :product_id + t.integer :cart_id + + t.timestamps + end + end +end diff --git a/db/migrate/20110711000004_add_quantity_to_line_items.rb b/db/migrate/20110711000004_add_quantity_to_line_items.rb new file mode 100644 index 0000000..935d871 --- /dev/null +++ b/db/migrate/20110711000004_add_quantity_to_line_items.rb @@ -0,0 +1,14 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class AddQuantityToLineItems < ActiveRecord::Migration + def change + add_column :line_items, :quantity, :integer, default: 1 + + end +end diff --git a/db/migrate/20110711000005_combine_items_in_cart.rb b/db/migrate/20110711000005_combine_items_in_cart.rb new file mode 100644 index 0000000..f96a10d --- /dev/null +++ b/db/migrate/20110711000005_combine_items_in_cart.rb @@ -0,0 +1,42 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class CombineItemsInCart < ActiveRecord::Migration + + def up + # replace multiple items for a single product in a cart with a single item + Cart.all.each do |cart| + # count the number of each product in the cart + sums = cart.line_items.group(:product_id).sum(:quantity) + + sums.each do |product_id, quantity| + if quantity > 1 + # remove individual items + cart.line_items.where(product_id: product_id).delete_all + + # replace with a single item + cart.line_items.create(product_id: product_id, quantity: quantity) + end + end + end + end + + def down + # split items with quantity>1 into multiple items + LineItem.where("quantity>1").each do |line_item| + # add individual items + line_item.quantity.times do + LineItem.create cart_id: line_item.cart_id, + product_id: line_item.product_id, quantity: 1 + end + + # remove original item + line_item.destroy + end + end +end diff --git a/db/migrate/20110711000006_add_price_to_line_item.rb b/db/migrate/20110711000006_add_price_to_line_item.rb new file mode 100644 index 0000000..384320c --- /dev/null +++ b/db/migrate/20110711000006_add_price_to_line_item.rb @@ -0,0 +1,17 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class AddPriceToLineItem < ActiveRecord::Migration + def change + add_column :line_items, :price, :decimal + LineItem.all.each do |li| + li.price = li.product.price + end + + end +end diff --git a/db/migrate/20110711000007_create_orders.rb b/db/migrate/20110711000007_create_orders.rb new file mode 100644 index 0000000..aed477b --- /dev/null +++ b/db/migrate/20110711000007_create_orders.rb @@ -0,0 +1,20 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class CreateOrders < ActiveRecord::Migration + def change + create_table :orders do |t| + t.string :name + t.text :address + t.string :email + t.string :pay_type + + t.timestamps + end + end +end diff --git a/db/migrate/20110711000008_add_order_id_to_line_item.rb b/db/migrate/20110711000008_add_order_id_to_line_item.rb new file mode 100644 index 0000000..a185f62 --- /dev/null +++ b/db/migrate/20110711000008_add_order_id_to_line_item.rb @@ -0,0 +1,14 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class AddOrderIdToLineItem < ActiveRecord::Migration + def change + add_column :line_items, :order_id, :integer + + end +end diff --git a/db/migrate/20110711000009_create_users.rb b/db/migrate/20110711000009_create_users.rb new file mode 100644 index 0000000..b7abb98 --- /dev/null +++ b/db/migrate/20110711000009_create_users.rb @@ -0,0 +1,18 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +class CreateUsers < ActiveRecord::Migration + def change + create_table :users do |t| + t.string :name + t.string :password_digest + + t.timestamps + end + end +end diff --git a/db/production.db b/db/production.db new file mode 100644 index 0000000..e69de29 diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..9fc3556 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,64 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20110711000009) do + + create_table "carts", :force => true do |t| + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "line_items", :force => true do |t| + t.integer "product_id" + t.integer "cart_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "quantity", :default => 1 + t.decimal "price" + t.integer "order_id" + end + + create_table "orders", :force => true do |t| + t.string "name" + t.text "address" + t.string "email" + t.string "pay_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "products", :force => true do |t| + t.string "title" + t.text "description" + t.string "image_url" + t.decimal "price", :precision => 8, :scale => 2 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "users", :force => true do |t| + t.string "name" + t.string "password_digest" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..ecd0730 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,45 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +# encoding: utf-8 +Product.delete_all +Product.create(title: 'CoffeeScript', + description: + %{

+ CoffeeScript is JavaScript done right. It provides all of JavaScript's + functionality wrapped in a cleaner, more succinct syntax. In the first + book on this exciting new language, CoffeeScript guru Trevor Burnham + shows you how to hold onto all the power and flexibility of JavaScript + while writing clearer, cleaner, and safer code. +

}, + image_url: 'cs.jpg', + price: 36.00) +# . . . +Product.create(title: 'Programming Ruby 1.9', + description: + %{

+ Ruby is the fastest growing and most exciting dynamic language + out there. If you need to get working programs delivered fast, + you should add Ruby to your toolbox. +

}, + image_url: 'ruby.jpg', + price: 49.95) +# . . . + +Product.create(title: 'Rails Test Prescriptions', + description: + %{

+ Rails Test Prescriptions is a comprehensive guide to testing + Rails applications, covering Test-Driven Development from both a + theoretical perspective (why to test) and from a practical perspective + (how to test effectively). It covers the core Rails testing tools and + procedures for Rails 2 and Rails 3, and introduces popular add-ons, + including Cucumber, Shoulda, Machinist, Mocha, and Rcov. +

}, + image_url: 'rtp.jpg', + price: 34.95) diff --git a/doc/README_FOR_APP b/doc/README_FOR_APP new file mode 100644 index 0000000..e0629bc --- /dev/null +++ b/doc/README_FOR_APP @@ -0,0 +1,37 @@ += The Depot Online Store + +This application implements an online store, with a catalog, cart, and orders. + +It is divided into two main sections: + +* The buyer's side of the application manages the catalog, cart, + and checkout. It is implementation spans in four models and associated + controllers and views: Cart, LineItem, Order, and Product. Additionally, + there is a StoreController for the store front itself, and a + SessionsController to manage sessions. + +* Only administrators can access stuff in the seller's side + (product maintenance and order fulfillment). This is implemented by the + LoginController, is enforced by the ApplicationController#authorize + method, and assisted by the Users and Carts resources. + +This code was produced as an example for the book {Agile Web Development with +Rails}[http://www.pragprog.com/titles/rails4/agile-web-development-with-rails-4th-edition]. It should not be +run as a real online store. + +=== Authors + + * Sam Ruby, IBM + * Dave Thomas, The Pragmatic Programmers, LLC + * David Heinemeier Hansson, 37signals + +=== Warranty + +This code is provided for educational purposes only, and comes with +absolutely no warranty. It should not be used in live applications. + +== Copyright + +This code is Copyright (c) 2010 The Pragmatic Programmers, LLC. + +It is released under the same license as Ruby. diff --git a/lib/assets/.gitkeep b/lib/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/.gitkeep b/lib/tasks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/db_backup.rake b/lib/tasks/db_backup.rake new file mode 100644 index 0000000..0ceef1a --- /dev/null +++ b/lib/tasks/db_backup.rake @@ -0,0 +1,14 @@ +namespace :db do + + desc "Backup the production database" + task :backup => :environment do + backup_dir = ENV['DIR'] || File.join(Rails.root, 'db', 'backup') + + source = File.join(Rails.root, 'db', "production.db") + dest = File.join(backup_dir, "production.backup") + + makedirs backup_dir, :verbose => true + sh "sqlite3 #{source} .dump > #{dest}" + end + +end diff --git a/lib/tasks/db_schema_migrations.rake b/lib/tasks/db_schema_migrations.rake new file mode 100644 index 0000000..da452bc --- /dev/null +++ b/lib/tasks/db_schema_migrations.rake @@ -0,0 +1,7 @@ +namespace :db do + desc "Prints the migrated versions" + task :schema_migrations => :environment do + puts ActiveRecord::Base.connection.select_values( + 'select version from schema_migrations order by version' ) + end +end diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..f1744ad --- /dev/null +++ b/public/404.html @@ -0,0 +1,34 @@ + + + + + The page you were looking for doesn't exist (404) + + + + + +
+

The page you were looking for doesn't exist.

+

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

+
+ + diff --git a/public/422.html b/public/422.html new file mode 100644 index 0000000..9b39931 --- /dev/null +++ b/public/422.html @@ -0,0 +1,34 @@ + + + + + The change you wanted was rejected (422) + + + + + +
+

The change you wanted was rejected.

+

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

+
+ + diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000..f6f4e31 --- /dev/null +++ b/public/500.html @@ -0,0 +1,33 @@ + + + + + We're sorry, but something went wrong (500) + + + + + +
+

We're sorry, but something went wrong.

+
+ + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..085187f --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-Agent: * +# Disallow: / diff --git a/script/creditcard.rb b/script/creditcard.rb new file mode 100644 index 0000000..f91ec56 --- /dev/null +++ b/script/creditcard.rb @@ -0,0 +1,18 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +credit_card = ActiveMerchant::Billing::CreditCard.new( + number: '4111111111111111', + month: '8', + year: '2009', + first_name: 'Tobias', + last_name: 'Luetke', + verification_value: '123' +) + +puts "Is #{credit_card.number} valid? #{credit_card.valid?}" diff --git a/script/load_orders.rb b/script/load_orders.rb new file mode 100644 index 0000000..217dc02 --- /dev/null +++ b/script/load_orders.rb @@ -0,0 +1,14 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +Order.transaction do + (1..100).each do |i| + Order.create(name: "Customer #{i}", address: "#{i} Main Street", + email: "customer-#{i}@example.com", pay_type: "Check") + end +end diff --git a/script/rails b/script/rails new file mode 100755 index 0000000..f8da2cf --- /dev/null +++ b/script/rails @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) +require 'rails/commands' diff --git a/store.ru b/store.ru new file mode 100644 index 0000000..783a82d --- /dev/null +++ b/store.ru @@ -0,0 +1,10 @@ +require 'rubygems' +require 'bundler/setup' + +require './app/store' + +use Rack::ShowExceptions + +map '/store' do + run StoreApp.new +end diff --git a/test/fixtures/.gitkeep b/test/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/carts.yml b/test/fixtures/carts.yml new file mode 100644 index 0000000..c63aac0 --- /dev/null +++ b/test/fixtures/carts.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/line_items.yml b/test/fixtures/line_items.yml new file mode 100644 index 0000000..28f7ef3 --- /dev/null +++ b/test/fixtures/line_items.yml @@ -0,0 +1,12 @@ +# Read about fixtures at +# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + product: ruby +#START_HIGHLIGHT + order: one +#END_HIGHLIGHT + +two: + product: ruby + cart: one diff --git a/test/fixtures/orders.yml b/test/fixtures/orders.yml new file mode 100644 index 0000000..68288d6 --- /dev/null +++ b/test/fixtures/orders.yml @@ -0,0 +1,20 @@ +# Read about fixtures at +# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: +#START_HIGHLIGHT + name: Dave Thomas +#END_HIGHLIGHT + address: MyText +#START_HIGHLIGHT + email: dave@example.org +#END_HIGHLIGHT +#START_HIGHLIGHT + pay_type: Check +#END_HIGHLIGHT + +two: + name: MyString + address: MyText + email: MyString + pay_type: MyString diff --git a/test/fixtures/products.yml b/test/fixtures/products.yml new file mode 100644 index 0000000..2f5e0a7 --- /dev/null +++ b/test/fixtures/products.yml @@ -0,0 +1,25 @@ +# Read about fixtures at +# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + title: MyString + description: MyText + image_url: MyString + price: 9.99 + +two: + title: MyString + description: MyText + image_url: MyString + price: 9.99 +#START:ruby + +ruby: + title: Programming Ruby 1.9 + description: + Ruby is the fastest growing and most exciting dynamic + language out there. If you need to get working programs + delivered fast, you should add Ruby to your toolbox. + price: 49.50 + image_url: ruby.png +#END:ruby diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..9f633d9 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,10 @@ +# Read about fixtures at +# http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + name: dave + password_digest: <%= BCrypt::Password.create('secret') %> + +two: + name: MyString + password_digest: MyString diff --git a/test/functional/.gitkeep b/test/functional/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/functional/admin_controller_test.rb b/test/functional/admin_controller_test.rb new file mode 100644 index 0000000..3050fc3 --- /dev/null +++ b/test/functional/admin_controller_test.rb @@ -0,0 +1,17 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class AdminControllerTest < ActionController::TestCase + test "should get index" do + get :index + assert_response :success + end + +end diff --git a/test/functional/carts_controller_test.rb b/test/functional/carts_controller_test.rb new file mode 100644 index 0000000..32d691a --- /dev/null +++ b/test/functional/carts_controller_test.rb @@ -0,0 +1,58 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class CartsControllerTest < ActionController::TestCase + setup do + @cart = carts(:one) + end + + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:carts) + end + + test "should get new" do + get :new + assert_response :success + end + + test "should create cart" do + assert_difference('Cart.count') do + post :create, cart: @cart.attributes + end + + assert_redirected_to cart_path(assigns(:cart)) + end + + test "should show cart" do + get :show, id: @cart + assert_response :success + end + + test "should get edit" do + get :edit, id: @cart + assert_response :success + end + + test "should update cart" do + put :update, id: @cart, cart: @cart.attributes + assert_redirected_to cart_path(assigns(:cart)) + end + + test "should destroy cart" do + assert_difference('Cart.count', -1) do + session[:cart_id] = @cart.id + delete :destroy, id: @cart + end + + assert_redirected_to store_path + end +end diff --git a/test/functional/line_items_controller_test.rb b/test/functional/line_items_controller_test.rb new file mode 100644 index 0000000..eb6f0e5 --- /dev/null +++ b/test/functional/line_items_controller_test.rb @@ -0,0 +1,68 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class LineItemsControllerTest < ActionController::TestCase + setup do + @line_item = line_items(:one) + end + + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:line_items) + end + + test "should get new" do + get :new + assert_response :success + end + + test "should create line_item" do + assert_difference('LineItem.count') do + post :create, product_id: products(:ruby).id + end + + assert_redirected_to store_path + end + + test "should show line_item" do + get :show, id: @line_item + assert_response :success + end + + test "should get edit" do + get :edit, id: @line_item + assert_response :success + end + + test "should update line_item" do + put :update, id: @line_item, line_item: @line_item.attributes + assert_redirected_to line_item_path(assigns(:line_item)) + end + + test "should destroy line_item" do + assert_difference('LineItem.count', -1) do + delete :destroy, id: @line_item + end + + assert_redirected_to line_items_path + end + + test "should create line_item via ajax" do + assert_difference('LineItem.count') do + xhr :post, :create, product_id: products(:ruby).id + end + + assert_response :success + assert_select_jquery :html, '#cart' do + assert_select 'tr#current_item td', /Programming Ruby 1.9/ + end + end +end diff --git a/test/functional/order_notifier_test.rb b/test/functional/order_notifier_test.rb new file mode 100644 index 0000000..a82a35d --- /dev/null +++ b/test/functional/order_notifier_test.rb @@ -0,0 +1,29 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class OrderNotifierTest < ActionMailer::TestCase + test "received" do + mail = OrderNotifier.received(orders(:one)) + assert_equal "Pragmatic Store Order Confirmation", mail.subject + assert_equal ["dave@example.org"], mail.to + assert_equal ["depot@example.com"], mail.from + assert_match /1 x Programming Ruby 1.9/, mail.body.encoded + end + + test "shipped" do + mail = OrderNotifier.shipped(orders(:one)) + assert_equal "Pragmatic Store Order Shipped", mail.subject + assert_equal ["dave@example.org"], mail.to + assert_equal ["depot@example.com"], mail.from + assert_match /1×<\/td>\s*Programming Ruby 1.9<\/td>/, + mail.body.encoded + end + +end diff --git a/test/functional/orders_controller_test.rb b/test/functional/orders_controller_test.rb new file mode 100644 index 0000000..54b2a9b --- /dev/null +++ b/test/functional/orders_controller_test.rb @@ -0,0 +1,67 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class OrdersControllerTest < ActionController::TestCase + setup do + @order = orders(:one) + end + + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:orders) + end + + test "requires item in cart" do + get :new + assert_redirected_to store_path + assert_equal flash[:notice], 'Your cart is empty' + end + + test "should get new" do + cart = Cart.create + session[:cart_id] = cart.id + LineItem.create(cart: cart, product: products(:ruby)) + + get :new + assert_response :success + end + + test "should create order" do + assert_difference('Order.count') do + post :create, order: @order.attributes + end + + assert_redirected_to store_path + end + + test "should show order" do + get :show, id: @order + assert_response :success + end + + test "should get edit" do + get :edit, id: @order + assert_response :success + end + + test "should update order" do + put :update, id: @order, order: @order.attributes + assert_redirected_to order_path(assigns(:order)) + end + + test "should destroy order" do + assert_difference('Order.count', -1) do + delete :destroy, id: @order + end + + assert_redirected_to orders_path + end +end diff --git a/test/functional/products_controller_test.rb b/test/functional/products_controller_test.rb new file mode 100644 index 0000000..c695535 --- /dev/null +++ b/test/functional/products_controller_test.rb @@ -0,0 +1,77 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class ProductsControllerTest < ActionController::TestCase + setup do + @product = products(:one) + @update = { + title: 'Lorem Ipsum', + description: 'Wibbles are fun!', + image_url: 'lorem.jpg', + price: 19.95 + } + end + + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:products) + end + + test "should get new" do + get :new + assert_response :success + end + + test "should create product" do + assert_difference('Product.count') do + post :create, product: @update + end + + assert_redirected_to product_path(assigns(:product)) + end + + test "should show product" do + get :show, id: @product + assert_response :success + end + + test "should get edit" do + get :edit, id: @product + assert_response :success + end + + test "should update product" do + put :update, id: @product, product: @update + assert_redirected_to product_path(assigns(:product)) + end + + test "can't delete product in cart" do + assert_difference('Product.count', 0) do + delete :destroy, id: products(:ruby) + end + + assert_redirected_to products_path + end + + test "should destroy product" do + assert_difference('Product.count', -1) do + delete :destroy, id: @product + end + + assert_redirected_to products_path + end + + test "should require login" do + logout + get :index + assert_redirected_to login_path + end +end diff --git a/test/functional/sessions_controller_test.rb b/test/functional/sessions_controller_test.rb new file mode 100644 index 0000000..14669b6 --- /dev/null +++ b/test/functional/sessions_controller_test.rb @@ -0,0 +1,35 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class SessionsControllerTest < ActionController::TestCase + test "should get new" do + get :new + assert_response :success + end + + test "should login" do + dave = users(:one) + post :create, name: dave.name, password: 'secret' + assert_redirected_to admin_url + assert_equal dave.id, session[:user_id] + end + + test "should fail login" do + dave = users(:one) + post :create, name: dave.name, password: 'wrong' + assert_redirected_to login_url + end + + test "should logout" do + delete :destroy + assert_redirected_to store_url + end + +end diff --git a/test/functional/store_controller_test.rb b/test/functional/store_controller_test.rb new file mode 100644 index 0000000..92fb944 --- /dev/null +++ b/test/functional/store_controller_test.rb @@ -0,0 +1,26 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class StoreControllerTest < ActionController::TestCase + test "should get index" do + get :index + assert_response :success + assert_select '#columns #side a', minimum: 4 + assert_select '#main .entry', 3 + assert_select 'h3', 'Programming Ruby 1.9' + assert_select '.price', /\$[,\d]+\.\d\d/ + end + + test "markup needed for store.js.coffee is in place" do + get :index + assert_select '.store .entry > img', 3 + assert_select '.entry input[type=submit]', 3 + end +end diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb new file mode 100644 index 0000000..acf1010 --- /dev/null +++ b/test/functional/users_controller_test.rb @@ -0,0 +1,65 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class UsersControllerTest < ActionController::TestCase + setup do + @input_attributes = { + name: "sam", + password: "private", + password_confirmation: "private" + } + + @user = users(:one) + end + + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:users) + end + + test "should get new" do + get :new + assert_response :success + end + + #... + test "should create user" do + assert_difference('User.count') do + post :create, user: @input_attributes + end + + assert_redirected_to users_path + end + + test "should show user" do + get :show, id: @user + assert_response :success + end + + test "should get edit" do + get :edit, id: @user + assert_response :success + end + + #... + test "should update user" do + put :update, id: @user, user: @input_attributes + assert_redirected_to users_path + end + + test "should destroy user" do + assert_difference('User.count', -1) do + delete :destroy, id: @user + end + + assert_redirected_to users_path + end +end diff --git a/test/integration/.gitkeep b/test/integration/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/integration/dsl_user_stories_test.rb b/test/integration/dsl_user_stories_test.rb new file mode 100644 index 0000000..2b39de7 --- /dev/null +++ b/test/integration/dsl_user_stories_test.rb @@ -0,0 +1,128 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class DslUserStoriesTest < ActionController::IntegrationTest + fixtures :products + + + DAVES_DETAILS = { + :name => "Dave Thomas", + :address => "123 The Street", + :email => "dave@example.com", + :pay_type => "Check" + } + + MIKES_DETAILS = { + :name => "Mike Clark", + :address => "345 The Avenue", + :email => "mike@pragmaticstudio.com", + :pay_type => "Credit card" + } + + + + def setup + LineItem.delete_all + Order.delete_all + @ruby_book = products(:ruby) + @rails_book = products(:two) + end + + # A user goes to the store index page. They select a product, + # adding it to their cart. They then check out, filling in + # their details on the checkout form. When they submit, + # an order is created in the database containing + # their information, along with a single line item + # corresponding to the product they added to their cart. + + def test_buying_a_product + dave = regular_user + dave.get "/" + dave.is_viewing "index" + dave.buys_a @ruby_book + dave.has_a_cart_containing @ruby_book + dave.checks_out DAVES_DETAILS + dave.is_viewing "index" + check_for_order DAVES_DETAILS, @ruby_book + end + + def test_two_people_buying + dave = regular_user + mike = regular_user + dave.buys_a @ruby_book + mike.buys_a @rails_book + dave.has_a_cart_containing @ruby_book + dave.checks_out DAVES_DETAILS + mike.has_a_cart_containing @rails_book + check_for_order DAVES_DETAILS, @ruby_book + mike.checks_out MIKES_DETAILS + check_for_order MIKES_DETAILS, @rails_book + end + + def regular_user + open_session do |user| + def user.is_viewing(page) + assert_response :success + assert_template page + end + + def user.buys_a(product) + xml_http_request :post, '/line_items', :product_id => product.id + assert_response :success + end + + def user.has_a_cart_containing(*products) + cart = Cart.find(session[:cart_id]) + assert_equal products.size, cart.line_items.size + cart.line_items.each do |item| + assert products.include?(item.product) + end + end + + def user.checks_out(details) + get "/orders/new" + assert_response :success + assert_template "new" + + post_via_redirect "/orders", + :order => { :name => details[:name], + :address => details[:address], + :email => details[:email], + :pay_type => details[:pay_type] + } + assert_response :success + assert_template "index" + cart = Cart.find(session[:cart_id]) + assert_equal 0, cart.line_items.size + end + end + end + + def check_for_order(details, *products) + order = Order.find_by_name(details[:name]) + assert_not_nil order + + assert_equal details[:name], order.name + assert_equal details[:address], order.address + assert_equal details[:email], order.email + assert_equal details[:pay_type], order.pay_type + + assert_equal products.size, order.line_items.size + for line_item in order.line_items + assert products.include?(line_item.product) + end + + mail = ActionMailer::Base.deliveries.last + assert_equal order.email, mail[:to].value + for line_item in order.line_items + assert_operator mail.body.to_s, :include?, line_item.product.title + end + end +end diff --git a/test/integration/user_stories_test.rb b/test/integration/user_stories_test.rb new file mode 100644 index 0000000..a964af7 --- /dev/null +++ b/test/integration/user_stories_test.rb @@ -0,0 +1,67 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class UserStoriesTest < ActionDispatch::IntegrationTest + fixtures :products + + # A user goes to the index page. They select a product, adding it to their + # cart, and check out, filling in their details on the checkout form. When + # they submit, an order is created containing their information, along with a + # single line item corresponding to the product they added to their cart. + + test "buying a product" do + LineItem.delete_all + Order.delete_all + ruby_book = products(:ruby) + + get "/" + assert_response :success + assert_template "index" + + xml_http_request :post, '/line_items', product_id: ruby_book.id + assert_response :success + + cart = Cart.find(session[:cart_id]) + assert_equal 1, cart.line_items.size + assert_equal ruby_book, cart.line_items[0].product + + get "/orders/new" + assert_response :success + assert_template "new" + + post_via_redirect "/orders", + order: { name: "Dave Thomas", + address: "123 The Street", + email: "dave@example.com", + pay_type: "Check" } + assert_response :success + assert_template "index" + cart = Cart.find(session[:cart_id]) + assert_equal 0, cart.line_items.size + + orders = Order.all + assert_equal 1, orders.size + order = orders[0] + + assert_equal "Dave Thomas", order.name + assert_equal "123 The Street", order.address + assert_equal "dave@example.com", order.email + assert_equal "Check", order.pay_type + + assert_equal 1, order.line_items.size + line_item = order.line_items[0] + assert_equal ruby_book, line_item.product + + mail = ActionMailer::Base.deliveries.last + assert_equal ["dave@example.com"], mail.to + assert_equal 'Sam Ruby ', mail[:from].value + assert_equal "Pragmatic Store Order Confirmation", mail.subject + end +end diff --git a/test/performance/browsing_test.rb b/test/performance/browsing_test.rb new file mode 100644 index 0000000..2e87a0b --- /dev/null +++ b/test/performance/browsing_test.rb @@ -0,0 +1,20 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' +require 'rails/performance_test_help' + +class BrowsingTest < ActionDispatch::PerformanceTest + # Refer to the documentation for all available options + # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] + # :output => 'tmp/performance', :formats => [:flat] } + + def test_homepage + get '/' + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..66207db --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,33 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +ENV["RAILS_ENV"] = "test" +require File.expand_path('../../config/environment', __FILE__) +require 'rails/test_help' + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. + # + # Note: You'll currently still have to declare fixtures explicitly in integration tests + # -- they do not yet inherit this setting + fixtures :all + # ... + + # Add more helper methods to be used by all tests here... + def login_as(user) + session[:user_id] = users(user).id + end + + def logout + session.delete :user_id + end + + def setup + login_as :one if defined? session + end +end diff --git a/test/unit/.gitkeep b/test/unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/unit/cart_test.rb b/test/unit/cart_test.rb new file mode 100644 index 0000000..b21d6ab --- /dev/null +++ b/test/unit/cart_test.rb @@ -0,0 +1,32 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class CartTest < ActiveSupport::TestCase + def setup + @cart = Cart.create + @book_one = products(:ruby) + @book_two = products(:two) + end + + test "add unique products" do + @cart.add_product(@book_one.id).save! + @cart.add_product(@book_two.id).save! + assert_equal 2, @cart.line_items.size + assert_equal @book_one.price + @book_two.price, @cart.total_price + end + + test "add duplicate product" do + @cart.add_product(@book_one.id).save! + @cart.add_product(@book_one.id).save! + assert_equal 2*@book_one.price, @cart.total_price + assert_equal 1, @cart.line_items.size + assert_equal 2, @cart.line_items[0].quantity + end +end diff --git a/test/unit/helpers/admin_helper_test.rb b/test/unit/helpers/admin_helper_test.rb new file mode 100644 index 0000000..580acfc --- /dev/null +++ b/test/unit/helpers/admin_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class AdminHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/carts_helper_test.rb b/test/unit/helpers/carts_helper_test.rb new file mode 100644 index 0000000..d1af4a5 --- /dev/null +++ b/test/unit/helpers/carts_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class CartsHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/line_items_helper_test.rb b/test/unit/helpers/line_items_helper_test.rb new file mode 100644 index 0000000..db0f7b8 --- /dev/null +++ b/test/unit/helpers/line_items_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class LineItemsHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/orders_helper_test.rb b/test/unit/helpers/orders_helper_test.rb new file mode 100644 index 0000000..0f97a7e --- /dev/null +++ b/test/unit/helpers/orders_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class OrdersHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/products_helper_test.rb b/test/unit/helpers/products_helper_test.rb new file mode 100644 index 0000000..4692cb5 --- /dev/null +++ b/test/unit/helpers/products_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class ProductsHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/sessions_helper_test.rb b/test/unit/helpers/sessions_helper_test.rb new file mode 100644 index 0000000..b70c52a --- /dev/null +++ b/test/unit/helpers/sessions_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class SessionsHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/store_helper_test.rb b/test/unit/helpers/store_helper_test.rb new file mode 100644 index 0000000..79bd25b --- /dev/null +++ b/test/unit/helpers/store_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class StoreHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/users_helper_test.rb b/test/unit/helpers/users_helper_test.rb new file mode 100644 index 0000000..ba43d62 --- /dev/null +++ b/test/unit/helpers/users_helper_test.rb @@ -0,0 +1,12 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class UsersHelperTest < ActionView::TestCase +end diff --git a/test/unit/line_item_test.rb b/test/unit/line_item_test.rb new file mode 100644 index 0000000..22b0c1e --- /dev/null +++ b/test/unit/line_item_test.rb @@ -0,0 +1,15 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class LineItemTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/unit/order_test.rb b/test/unit/order_test.rb new file mode 100644 index 0000000..11161cd --- /dev/null +++ b/test/unit/order_test.rb @@ -0,0 +1,15 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class OrderTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/unit/product_test.rb b/test/unit/product_test.rb new file mode 100644 index 0000000..cdeff40 --- /dev/null +++ b/test/unit/product_test.rb @@ -0,0 +1,81 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class ProductTest < ActiveSupport::TestCase + test "product attributes must not be empty" do + product = Product.new + assert product.invalid? + assert product.errors[:title].any? + assert product.errors[:description].any? + assert product.errors[:price].any? + assert product.errors[:image_url].any? + end + + test "product price must be positive" do + product = Product.new(title: "My Book Title", + description: "yyy", + image_url: "zzz.jpg") + product.price = -1 + assert product.invalid? + assert_equal "must be greater than or equal to 0.01", + product.errors[:price].join('; ') + + product.price = 0 + assert product.invalid? + assert_equal "must be greater than or equal to 0.01", + product.errors[:price].join('; ') + + product.price = 1 + assert product.valid? + end + + def new_product(image_url) + Product.new(title: "My Book Title", + description: "yyy", + price: 1, + image_url: image_url) + end + + test "image url" do + ok = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg + http://a.b.c/x/y/z/fred.gif } + bad = %w{ fred.doc fred.gif/more fred.gif.more } + + ok.each do |name| + assert new_product(name).valid?, "#{name} shouldn't be invalid" + end + + bad.each do |name| + assert new_product(name).invalid?, "#{name} shouldn't be valid" + end + end + + test "product is not valid without a unique title" do + product = Product.new(title: products(:ruby).title, + description: "yyy", + price: 1, + image_url: "fred.gif") + + assert !product.save + assert_equal "has already been taken", product.errors[:title].join('; ') + end + + test "product is not valid without a unique title - i18n" do + product = Product.new(title: products(:ruby).title, + description: "yyy", + price: 1, + image_url: "fred.gif") + + assert !product.save + assert_equal I18n.translate('activerecord.errors.messages.taken'), + product.errors[:title].join('; ') + end + +end diff --git a/test/unit/routing_test.rb b/test/unit/routing_test.rb new file mode 100644 index 0000000..c5aa3bb --- /dev/null +++ b/test/unit/routing_test.rb @@ -0,0 +1,50 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' +require './config/routes.rb' + +class RoutingTest < ActionController::TestCase + + def test_recognizes + # Check the default index action gets generated + assert_recognizes({"controller" => "store", "action" => "index"}, "/") + + # Check routing to an action + assert_recognizes({"controller" => "products", "action" => "index"}, + "/products") + + # And routing with a parameter + assert_recognizes({ "controller" => "line_items", + "action" => "create", + "product_id" => "1" }, + {path: "/line_items", method: :post}, + {"product_id" => "1"}) + end + + def test_generates + assert_generates("/", controller: "store", action: "index") + assert_generates("/products", + { controller: "products", action: "index"}) + assert_generates("/line_items", + { controller: "line_items", action: "create", + product_id: "1"}, + {method: :post}, { product_id: "1"}) + end + + def test_routing + assert_routing("/", controller: "store", action: "index") + assert_routing("/products", controller: "products", action: "index") + assert_routing({path: "/line_items", method: :post}, + { controller: "line_items", action: "create", + product_id: "1"}, + {}, { product_id: "1"}) + end + +end + diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb new file mode 100644 index 0000000..9ad93d9 --- /dev/null +++ b/test/unit/user_test.rb @@ -0,0 +1,15 @@ +#--- +# Excerpted from "Agile Web Development with Rails", +# published by The Pragmatic Bookshelf. +# Copyrights apply to this code. It may not be used to create training material, +# courses, books, articles, and the like. Contact us if you are in doubt. +# We make no guarantees that this code is fit for any purpose. +# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information. +#--- +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/vendor/assets/javascripts/.gitkeep b/vendor/assets/javascripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/stylesheets/.gitkeep b/vendor/assets/stylesheets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/cache/i18n-0.6.0.gem b/vendor/cache/i18n-0.6.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..1ad8176f139e8bb8cbb38b8029eac84a8d7a574d GIT binary patch literal 60928 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 E0MuDJ$^ZZW literal 0 HcmV?d00001 diff --git a/vendor/cache/multi_json-1.0.4.gem b/vendor/cache/multi_json-1.0.4.gem new file mode 100644 index 0000000000000000000000000000000000000000..2c862408fd3d37f1dbf8ba5295d7037436a234a9 GIT binary patch literal 14336 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 HX5ha7sM#En literal 0 HcmV?d00001 diff --git a/vendor/cache/rake-0.9.2.2.gem b/vendor/cache/rake-0.9.2.2.gem new file mode 100644 index 0000000000000000000000000000000000000000..f7239ac279f50c692ff3d13af9df53e84889938c GIT binary patch literal 111616 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 vzO|M9V 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 literal 0 HcmV?d00001