From 9e9809596205224b22b8abfbdc96a5fe20d2d200 Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Mon, 7 May 2018 12:00:45 -0700 Subject: [PATCH 01/23] ran rails new --- .gitignore | 16 ++ Gemfile | 50 ++++++ Gemfile.lock | 154 ++++++++++++++++++ Rakefile | 6 + app/channels/application_cable/channel.rb | 4 + app/channels/application_cable/connection.rb | 4 + app/controllers/application_controller.rb | 2 + app/controllers/concerns/.keep | 0 app/jobs/application_job.rb | 2 + app/mailers/application_mailer.rb | 4 + app/models/application_record.rb | 3 + app/models/concerns/.keep | 0 app/views/layouts/mailer.html.erb | 13 ++ app/views/layouts/mailer.text.erb | 1 + bin/bundle | 3 + bin/rails | 9 + bin/rake | 9 + bin/setup | 35 ++++ bin/spring | 17 ++ bin/update | 29 ++++ config.ru | 5 + config/application.rb | 40 +++++ config/boot.rb | 3 + config/cable.yml | 10 ++ config/database.yml | 85 ++++++++++ config/environment.rb | 5 + config/environments/development.rb | 47 ++++++ config/environments/production.rb | 83 ++++++++++ config/environments/test.rb | 42 +++++ .../application_controller_renderer.rb | 8 + config/initializers/backtrace_silencers.rb | 7 + config/initializers/cors.rb | 16 ++ .../initializers/filter_parameter_logging.rb | 4 + config/initializers/inflections.rb | 16 ++ config/initializers/mime_types.rb | 4 + config/initializers/wrap_parameters.rb | 14 ++ config/locales/en.yml | 33 ++++ config/puma.rb | 56 +++++++ config/routes.rb | 3 + config/secrets.yml | 32 ++++ config/spring.rb | 6 + lib/tasks/.keep | 0 log/.keep | 0 public/robots.txt | 1 + test/controllers/.keep | 0 test/fixtures/.keep | 0 test/fixtures/files/.keep | 0 test/integration/.keep | 0 test/mailers/.keep | 0 test/models/.keep | 0 test/test_helper.rb | 26 +++ tmp/.keep | 0 vendor/.keep | 0 53 files changed, 907 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Rakefile create mode 100644 app/channels/application_cable/channel.rb create mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/concerns/.keep create mode 100644 app/jobs/application_job.rb create mode 100644 app/mailers/application_mailer.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100755 bin/bundle create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/setup create mode 100755 bin/spring create mode 100755 bin/update create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/cable.yml create mode 100644 config/database.yml 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/application_controller_renderer.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/cors.rb create mode 100644 config/initializers/filter_parameter_logging.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/puma.rb create mode 100644 config/routes.rb create mode 100644 config/secrets.yml create mode 100644 config/spring.rb create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 public/robots.txt create mode 100644 test/controllers/.keep create mode 100644 test/fixtures/.keep create mode 100644 test/fixtures/files/.keep create mode 100644 test/integration/.keep create mode 100644 test/mailers/.keep create mode 100644 test/models/.keep create mode 100644 test/test_helper.rb create mode 100644 tmp/.keep create mode 100644 vendor/.keep diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..68ac019ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +.byebug_history diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..78bff8d26 --- /dev/null +++ b/Gemfile @@ -0,0 +1,50 @@ +source 'https://rubygems.org' + +git_source(:github) do |repo_name| + repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") + "https://github.com/#{repo_name}.git" +end + + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '~> 5.1.6' +# Use postgresql as the database for Active Record +gem 'pg', '>= 0.18', '< 2.0' +# Use Puma as the app server +gem 'puma', '~> 3.7' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +# gem 'jbuilder', '~> 2.5' +# Use Redis adapter to run Action Cable in production +# gem 'redis', '~> 4.0' +# Use ActiveModel has_secure_password +# gem 'bcrypt', '~> 3.1.7' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible +# gem 'rack-cors' + +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] +end + +group :development do + gem 'listen', '>= 3.0.5', '< 3.2' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' + gem 'spring-watcher-listen', '~> 2.0.0' +end + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +group :development, :test do + gem 'pry-rails' +end + +group :test do + gem 'minitest-rails' + gem 'minitest-reporters' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..e547d2449 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,154 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.1.6) + actionpack (= 5.1.6) + nio4r (~> 2.0) + websocket-driver (~> 0.6.1) + actionmailer (5.1.6) + actionpack (= 5.1.6) + actionview (= 5.1.6) + activejob (= 5.1.6) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.1.6) + actionview (= 5.1.6) + activesupport (= 5.1.6) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.1.6) + activesupport (= 5.1.6) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.1.6) + activesupport (= 5.1.6) + globalid (>= 0.3.6) + activemodel (5.1.6) + activesupport (= 5.1.6) + activerecord (5.1.6) + activemodel (= 5.1.6) + activesupport (= 5.1.6) + arel (~> 8.0) + activesupport (5.1.6) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + ansi (1.5.0) + arel (8.0.0) + builder (3.2.3) + byebug (10.0.2) + coderay (1.1.2) + concurrent-ruby (1.0.5) + crass (1.0.4) + erubi (1.7.1) + ffi (1.9.23) + globalid (0.4.1) + activesupport (>= 4.2.0) + i18n (1.0.1) + concurrent-ruby (~> 1.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + loofah (2.2.2) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.0) + mini_mime (>= 0.1.1) + method_source (0.9.0) + mini_mime (1.0.0) + mini_portile2 (2.3.0) + minitest (5.11.3) + minitest-rails (3.0.0) + minitest (~> 5.8) + railties (~> 5.0) + minitest-reporters (1.2.0) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + nio4r (2.3.1) + nokogiri (1.8.2) + mini_portile2 (~> 2.3.0) + pg (1.0.0) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry-rails (0.3.6) + pry (>= 0.10.4) + puma (3.11.4) + rack (2.0.5) + rack-test (1.0.0) + rack (>= 1.0, < 3) + rails (5.1.6) + actioncable (= 5.1.6) + actionmailer (= 5.1.6) + actionpack (= 5.1.6) + actionview (= 5.1.6) + activejob (= 5.1.6) + activemodel (= 5.1.6) + activerecord (= 5.1.6) + activesupport (= 5.1.6) + bundler (>= 1.3.0) + railties (= 5.1.6) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.4) + loofah (~> 2.2, >= 2.2.2) + railties (5.1.6) + actionpack (= 5.1.6) + activesupport (= 5.1.6) + method_source + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (12.3.1) + rb-fsevent (0.10.3) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + ruby-progressbar (1.9.0) + ruby_dep (1.5.0) + spring (2.0.2) + activesupport (>= 4.2) + spring-watcher-listen (2.0.1) + listen (>= 2.7, < 4.0) + spring (>= 1.2, < 3.0) + sprockets (3.7.1) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.1) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.20.0) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.3) + +PLATFORMS + ruby + +DEPENDENCIES + byebug + listen (>= 3.0.5, < 3.2) + minitest-rails + minitest-reporters + pg (>= 0.18, < 2.0) + pry-rails + puma (~> 3.7) + rails (~> 5.1.6) + spring + spring-watcher-listen (~> 2.0.0) + tzinfo-data + +BUNDLED WITH + 1.16.1 diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..e85f91391 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# 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_relative 'config/application' + +Rails.application.load_tasks diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 000000000..d67269728 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 000000000..0ff5442f4 --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 000000000..4ac8823b0 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::API +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 000000000..a009ace51 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 000000000..286b2239d --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..10a4cba84 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 000000000..cbd34d2e9 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 000000000..37f0bddbd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 000000000..66e9889e8 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 000000000..5badb2fde --- /dev/null +++ b/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 000000000..d87d5f578 --- /dev/null +++ b/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 000000000..104e40c1c --- /dev/null +++ b/bin/setup @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:setup' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/bin/spring b/bin/spring new file mode 100755 index 000000000..fb2ec2ebb --- /dev/null +++ b/bin/spring @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) + spring = lockfile.specs.detect { |spec| spec.name == "spring" } + if spring + Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path + gem 'spring', spring.version + require 'spring/binstub' + end +end diff --git a/bin/update b/bin/update new file mode 100755 index 000000000..a8e4462f2 --- /dev/null +++ b/bin/update @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/config.ru b/config.ru new file mode 100644 index 000000000..f7ba0b527 --- /dev/null +++ b/config.ru @@ -0,0 +1,5 @@ +# This file is used by Rack-based servers to start the application. + +require_relative 'config/environment' + +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 000000000..2fe7718ea --- /dev/null +++ b/config/application.rb @@ -0,0 +1,40 @@ +require_relative 'boot' + +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "action_view/railtie" +require "action_cable/engine" +# require "sprockets/railtie" +require "rails/test_unit/railtie" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module VideoStoreAPI + class Application < Rails::Application + config.generators do |g| + # Force new test files to be generated in the minitest-spec style + g.test_framework :minitest, spec: true + + # Always use .js files, never .coffee + g.javascript_engine :js + end + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 5.1 + + # 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. + + # Only loads a smaller set of middleware suitable for API only apps. + # Middleware like session, flash, cookies can be added back manually. + # Skip views, helpers and assets when generating a new resource. + config.api_only = true + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 000000000..30f5120df --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..ad59bcd88 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: redis://localhost:6379/1 + channel_prefix: VideoStoreAPI_production diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 000000000..720570700 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,85 @@ +# PostgreSQL. Versions 9.1 and up are supported. +# +# Install the pg driver: +# gem install pg +# On OS X with Homebrew: +# gem install pg -- --with-pg-config=/usr/local/bin/pg_config +# On OS X with MacPorts: +# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config +# On Windows: +# gem install pg +# Choose the win32 build. +# Install PostgreSQL and put its /bin directory on your path. +# +# Configure Using Gemfile +# gem 'pg' +# +default: &default + adapter: postgresql + encoding: unicode + # For details on connection pooling, see Rails configuration guide + # http://guides.rubyonrails.org/configuring.html#database-pooling + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + +development: + <<: *default + database: VideoStoreAPI_development + + # The specified database role being used to connect to postgres. + # To create additional roles in postgres see `$ createuser --help`. + # When left blank, postgres will use the default role. This is + # the same name as the operating system user that initialized the database. + #username: VideoStoreAPI + + # The password associated with the postgres role (username). + #password: + + # Connect on a TCP socket. Omitted by default since the client uses a + # domain socket that doesn't need configuration. Windows does not have + # domain sockets, so uncomment these lines. + #host: localhost + + # The TCP port the server listens on. Defaults to 5432. + # If your server runs on a different port number, change accordingly. + #port: 5432 + + # Schema search path. The server defaults to $user,public + #schema_search_path: myapp,sharedapp,public + + # Minimum log levels, in increasing order: + # debug5, debug4, debug3, debug2, debug1, + # log, notice, warning, error, fatal, and panic + # Defaults to warning. + #min_messages: notice + +# 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: + <<: *default + database: VideoStoreAPI_test + +# As with config/secrets.yml, you never want to store sensitive information, +# like your database password, in your source code. If your source code is +# ever seen by anyone, they now have access to your database. +# +# Instead, provide the password as a unix environment variable when you boot +# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database +# for a full rundown on how to provide these environment variables in a +# production deployment. +# +# On Heroku and other platform providers, you may have a full connection URL +# available as an environment variable. For example: +# +# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" +# +# You can use this database configuration with: +# +# production: +# url: <%= ENV['DATABASE_URL'] %> +# +production: + <<: *default + database: VideoStoreAPI_production + username: VideoStoreAPI + password: <%= ENV['VIDEOSTOREAPI_DATABASE_PASSWORD'] %> diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 000000000..426333bb4 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative 'application' + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 000000000..abc82221c --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,47 @@ +Rails.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 + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + if Rails.root.join('tmp/caching-dev.txt').exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true + + # Use an evented file watcher to asynchronously detect changes in source code, + # routes, locales, etc. This feature depends on the listen gem. + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 000000000..3bd8115ea --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,83 @@ +Rails.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 + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Attempt to read encrypted secrets from `config/secrets.yml.enc`. + # Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or + # `config/secrets.yml.key`. + config.read_encrypted_secrets = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # 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 + + # Mount Action Cable outside main process or domain + # config.action_cable.mount_path = nil + # config.action_cable.url = 'wss://example.com/cable' + # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment) + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "VideoStoreAPI_#{Rails.env}" + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 000000000..8e5cbde53 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,42 @@ +Rails.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 + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}" + } + + # 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 + config.action_mailer.perform_caching = 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 + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100644 index 000000000..89d2efab2 --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 000000000..59385cdf3 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# 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/cors.rb b/config/initializers/cors.rb new file mode 100644 index 000000000..3b1c1b5ed --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Avoid CORS issues when API is called from the frontend app. +# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests. + +# Read more: https://github.com/cyu/rack-cors + +# Rails.application.config.middleware.insert_before 0, Rack::Cors do +# allow do +# origins 'example.com' +# +# resource '*', +# headers: :any, +# methods: [:get, :post, :put, :patch, :delete, :options, :head] +# end +# end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 000000000..4a994e1e7 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 000000000..ac033bf9d --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) 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(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 000000000..dc1899682 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# 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 diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 000000000..bbfc3961b --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# 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 + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 000000000..decc5a857 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,33 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# The following keys must be escaped otherwise they will not be retrieved by +# the default I18n backend: +# +# true, false, on, off, yes, no +# +# Instead, surround them with single quotes. +# +# en: +# 'true': 'foo' +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 000000000..1e19380dc --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,56 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked webserver processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. If you use this option +# you need to make sure to reconnect any threads in the `on_worker_boot` +# block. +# +# preload_app! + +# If you are preloading your application and using Active Record, it's +# recommended that you close any connections to the database before workers +# are forked to prevent connection leakage. +# +# before_fork do +# ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) +# end + +# The code in the `on_worker_boot` will be called if you are using +# clustered mode by specifying a number of `workers`. After each worker +# process is booted, this block will be run. If you are using the `preload_app!` +# option, you will want to use this block to reconnect to any threads +# or connections that may have been created at application boot, as Ruby +# cannot share connections between processes. +# +# on_worker_boot do +# ActiveRecord::Base.establish_connection if defined?(ActiveRecord) +# end +# + +# Allow puma to be restarted by `rails restart` command. +plugin :tmp_restart diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 000000000..787824f88 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,3 @@ +Rails.application.routes.draw do + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 000000000..e0456a7da --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,32 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used 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. +# You can use `rails secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +# Shared secrets are available across all environments. + +# shared: +# api_key: a1B2c3D4e5F6 + +# Environmental secrets are only available for that specific environment. + +development: + secret_key_base: 694ac7c01e172bb49a1105edf3465d1fba06f8bf030b40ed3d5f5216ca0d6c8fa90f6342ddabeb2a37dd1066b67f402a50e91171db123329c3d2822a4ec265ff + +test: + secret_key_base: df4befa957331e1f654ad68ef2c4e12bb1c706606bd0636d2e68dbff55896e2e965f75d5d00d32063b6d162c20b181be9f8e6bf4aacaa41cd20287c7f2172353 + +# Do not keep production secrets in the unencrypted secrets file. +# Instead, either read values from the environment. +# Or, use `bin/rails secrets:setup` to configure encrypted secrets +# and move the `production:` environment over there. + +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 000000000..c9119b40c --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w( + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +).each { |path| Spring.watch(path) } diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/log/.keep b/log/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 000000000..37b576a4a --- /dev/null +++ b/public/robots.txt @@ -0,0 +1 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/.keep b/test/fixtures/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 000000000..10594a324 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,26 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path("../../config/environment", __FILE__) +require "rails/test_help" +require "minitest/rails" +require "minitest/reporters" # for Colorized output + +# For colorful output! +Minitest::Reporters.use!( + Minitest::Reporters::SpecReporter.new, + ENV, + Minitest.backtrace_filter +) + + +# To add Capybara feature tests add `gem "minitest-rails-capybara"` +# to the test group in the Gemfile and uncomment the following: +# require "minitest/rails/capybara" + +# Uncomment for awesome colorful output +# require "minitest/pride" + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + # Add more helper methods to be used by all tests here... +end diff --git a/tmp/.keep b/tmp/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/.keep b/vendor/.keep new file mode 100644 index 000000000..e69de29bb From eeaef79e1f182b55e3792842ccd7de943bdfefd6 Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Mon, 7 May 2018 12:40:51 -0700 Subject: [PATCH 02/23] created models customer, movie, rental --- app/models/customer.rb | 2 + app/models/movie.rb | 2 + app/models/rental.rb | 2 + db/migrate/20180507193059_create_customers.rb | 14 ++++++ db/migrate/20180507193633_create_movies.rb | 12 +++++ db/migrate/20180507193744_create_rentals.rb | 11 +++++ db/schema.rb | 48 +++++++++++++++++++ test/fixtures/customers.yml | 11 +++++ test/fixtures/movies.yml | 11 +++++ test/fixtures/rentals.yml | 11 +++++ test/models/customer_test.rb | 9 ++++ test/models/movie_test.rb | 9 ++++ test/models/rental_test.rb | 9 ++++ 13 files changed, 151 insertions(+) create mode 100644 app/models/customer.rb create mode 100644 app/models/movie.rb create mode 100644 app/models/rental.rb create mode 100644 db/migrate/20180507193059_create_customers.rb create mode 100644 db/migrate/20180507193633_create_movies.rb create mode 100644 db/migrate/20180507193744_create_rentals.rb create mode 100644 db/schema.rb create mode 100644 test/fixtures/customers.yml create mode 100644 test/fixtures/movies.yml create mode 100644 test/fixtures/rentals.yml create mode 100644 test/models/customer_test.rb create mode 100644 test/models/movie_test.rb create mode 100644 test/models/rental_test.rb diff --git a/app/models/customer.rb b/app/models/customer.rb new file mode 100644 index 000000000..0b5277335 --- /dev/null +++ b/app/models/customer.rb @@ -0,0 +1,2 @@ +class Customer < ApplicationRecord +end diff --git a/app/models/movie.rb b/app/models/movie.rb new file mode 100644 index 000000000..dc614df15 --- /dev/null +++ b/app/models/movie.rb @@ -0,0 +1,2 @@ +class Movie < ApplicationRecord +end diff --git a/app/models/rental.rb b/app/models/rental.rb new file mode 100644 index 000000000..79e3a65ca --- /dev/null +++ b/app/models/rental.rb @@ -0,0 +1,2 @@ +class Rental < ApplicationRecord +end diff --git a/db/migrate/20180507193059_create_customers.rb b/db/migrate/20180507193059_create_customers.rb new file mode 100644 index 000000000..f597114c5 --- /dev/null +++ b/db/migrate/20180507193059_create_customers.rb @@ -0,0 +1,14 @@ +class CreateCustomers < ActiveRecord::Migration[5.1] + def change + create_table :customers do |t| + t.string :name + t.string :address + t.string :city + t.string :state + t.string :postal_code + t.string :phone_number + + t.timestamps + end + end +end diff --git a/db/migrate/20180507193633_create_movies.rb b/db/migrate/20180507193633_create_movies.rb new file mode 100644 index 000000000..62885a98f --- /dev/null +++ b/db/migrate/20180507193633_create_movies.rb @@ -0,0 +1,12 @@ +class CreateMovies < ActiveRecord::Migration[5.1] + def change + create_table :movies do |t| + t.string :title + t.string :overview + t.date :release_date + t.integer :inventory + + t.timestamps + end + end +end diff --git a/db/migrate/20180507193744_create_rentals.rb b/db/migrate/20180507193744_create_rentals.rb new file mode 100644 index 000000000..4842114cc --- /dev/null +++ b/db/migrate/20180507193744_create_rentals.rb @@ -0,0 +1,11 @@ +class CreateRentals < ActiveRecord::Migration[5.1] + def change + create_table :rentals do |t| + t.belongs_to :customer, index: true + t.belongs_to :movie, index: true + t.date :due_date + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..c95ed023d --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,48 @@ +# 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 that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20180507193744) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "customers", force: :cascade do |t| + t.string "name" + t.string "address" + t.string "city" + t.string "state" + t.string "postal_code" + t.string "phone_number" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "movies", force: :cascade do |t| + t.string "title" + t.string "overview" + t.date "release_date" + t.integer "inventory" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "rentals", force: :cascade do |t| + t.bigint "customer_id" + t.bigint "movie_id" + t.date "due_date" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["customer_id"], name: "index_rentals_on_customer_id" + t.index ["movie_id"], name: "index_rentals_on_movie_id" + end + +end diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml new file mode 100644 index 000000000..dc3ee79b5 --- /dev/null +++ b/test/fixtures/customers.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.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/movies.yml b/test/fixtures/movies.yml new file mode 100644 index 000000000..dc3ee79b5 --- /dev/null +++ b/test/fixtures/movies.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.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/rentals.yml b/test/fixtures/rentals.yml new file mode 100644 index 000000000..dc3ee79b5 --- /dev/null +++ b/test/fixtures/rentals.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.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/models/customer_test.rb b/test/models/customer_test.rb new file mode 100644 index 000000000..5ebc5c850 --- /dev/null +++ b/test/models/customer_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Customer do + let(:customer) { Customer.new } + + it "must be valid" do + value(customer).must_be :valid? + end +end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb new file mode 100644 index 000000000..34d1d30a5 --- /dev/null +++ b/test/models/movie_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Movie do + let(:movie) { Movie.new } + + it "must be valid" do + value(movie).must_be :valid? + end +end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb new file mode 100644 index 000000000..6ea53d94f --- /dev/null +++ b/test/models/rental_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Rental do + let(:rental) { Rental.new } + + it "must be valid" do + value(rental).must_be :valid? + end +end From decf6bfb51fa830de5700fddd2ea465d7f3a74f9 Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Mon, 7 May 2018 12:45:46 -0700 Subject: [PATCH 03/23] fixed table columns and ran db:seed --- db/migrate/20180507194203_add_registeredat_to_customer.rb | 5 +++++ .../20180507194319_update_customer_phoneno_to_phone.rb | 5 +++++ db/schema.rb | 5 +++-- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20180507194203_add_registeredat_to_customer.rb create mode 100644 db/migrate/20180507194319_update_customer_phoneno_to_phone.rb diff --git a/db/migrate/20180507194203_add_registeredat_to_customer.rb b/db/migrate/20180507194203_add_registeredat_to_customer.rb new file mode 100644 index 000000000..6d436bcc7 --- /dev/null +++ b/db/migrate/20180507194203_add_registeredat_to_customer.rb @@ -0,0 +1,5 @@ +class AddRegisteredatToCustomer < ActiveRecord::Migration[5.1] + def change + add_column :customers, :registered_at, :datetime + end +end diff --git a/db/migrate/20180507194319_update_customer_phoneno_to_phone.rb b/db/migrate/20180507194319_update_customer_phoneno_to_phone.rb new file mode 100644 index 000000000..3c620a22b --- /dev/null +++ b/db/migrate/20180507194319_update_customer_phoneno_to_phone.rb @@ -0,0 +1,5 @@ +class UpdateCustomerPhonenoToPhone < ActiveRecord::Migration[5.1] + def change + rename_column :customers, :phone_number, :phone + end +end diff --git a/db/schema.rb b/db/schema.rb index c95ed023d..162abb345 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180507193744) do +ActiveRecord::Schema.define(version: 20180507194319) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -21,9 +21,10 @@ t.string "city" t.string "state" t.string "postal_code" - t.string "phone_number" + t.string "phone" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.datetime "registered_at" end create_table "movies", force: :cascade do |t| From 64eaa54fc75454e5894d07a91da0b0c4febc5410 Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Mon, 7 May 2018 13:56:51 -0700 Subject: [PATCH 04/23] wrote movie model validations --- app/models/movie.rb | 11 ++++++++++ test/models/movie_test.rb | 46 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index dc614df15..c0ee4b177 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,2 +1,13 @@ class Movie < ApplicationRecord + validates :title, presence: true + validates :inventory, presence: true, numericality: { only_integer: true, greater_than: 0 } + validate :uniq_title_release_date_combo + + def uniq_title_release_date_combo + movies = Movie.where(title: title) + + if movies.any?{ |movie| movie.release_date == release_date } + errors[:release_date] << 'Cannot have a movie with the same title and release date' + end + end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 34d1d30a5..9a5f2aa11 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -1,9 +1,49 @@ require "test_helper" describe Movie do - let(:movie) { Movie.new } + describe 'validations' do + it 'must have a title' do + movie = Movie.new( + title: nil, + inventory: 2 + ) - it "must be valid" do - value(movie).must_be :valid? + movie.valid?.must_equal false + movie.errors.messages.must_include :title + end + + it 'must have an inventory as an integer greater than 0' do + movie = Movie.new( + title: 'A movie title', + inventory: nil + ) + + movie2 = Movie.new( + title: 'Another title', + inventory: -1 + ) + + movie.valid?.must_equal false + movie.errors.messages.must_include :inventory + movie2.valid?.must_equal false + movie2.errors.messages.must_include :inventory + end + + it 'will not allow a movie with the same title and same release_date' do + movie = Movie.create!( + title: 'A movie title', + inventory: 1, + release_date: Date.new(2018,04,02) + ) + + movie2 = Movie.new( + title: movie.title, + inventory: 1, + release_date: movie.release_date + ) + + movie2.valid?.must_equal false + movie2.errors.messages.must_include :release_date + end end end From 58e61301acc93ecfc293a139733bb109bd8cb89f Mon Sep 17 00:00:00 2001 From: Wenjie Date: Mon, 7 May 2018 14:10:27 -0700 Subject: [PATCH 05/23] Added model validations Implemented tests for customer model validations --- app/models/customer.rb | 11 +++++++++ test/models/customer_test.rb | 46 +++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/app/models/customer.rb b/app/models/customer.rb index 0b5277335..bb7ab7822 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,2 +1,13 @@ class Customer < ApplicationRecord + validates :name, presence: true + validates :phone, presence: true + validate :same_name_and_same_phone + + def same_name_and_same_phone + customers = Customer.where(name: name) + + if customers.any? {|customer| customer.phone == phone} + errors[:phone] << "Can not have the same name and same phone number" + end + end end diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 5ebc5c850..05c608ac9 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -1,9 +1,49 @@ require "test_helper" describe Customer do - let(:customer) { Customer.new } + describe "validations" do + before do + @customer = Customer.new( + name: "coco", + address: "114 Pine St.", + city: "Seattle", + state: "Washington", + postal_code: "98100", + phone: "(206) 206 2066" + ) + end - it "must be valid" do - value(customer).must_be :valid? + it "can be created with sufficient data" do + result = @customer.valid? + result.must_equal true + end + + it "can not be created without a name" do + @customer.name = "" + result = @customer.valid? + result.must_equal false + end + + it "can not be created without a phone number" do + @customer.phone = "" + result = @customer.valid? + result.must_equal false + end + + it "can not be created if with same name and same phone as existed customer" do + customer1 = Customer.new( + name: "coco", + address: "1232314 Pine St.", + city: "Portland", + state: "Oregon", + postal_code: "98100", + phone: "(206) 206 2066" + ) + + @customer.save + result = customer1.valid? + result.must_equal false + customer1.errors.messages.must_include :phone + end end end From 1c94d5e5e28e4aaa318f5275ae2a279f010acaae Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Mon, 7 May 2018 14:27:20 -0700 Subject: [PATCH 06/23] created tests and controller for customers --- app/controllers/customers_controller.rb | 7 +++++ app/controllers/movies_controller.rb | 4 +++ config/routes.rb | 3 ++ test/controllers/customers_controller_test.rb | 31 +++++++++++++++++++ test/controllers/movies_controller_test.rb | 7 +++++ 5 files changed, 52 insertions(+) create mode 100644 app/controllers/customers_controller.rb create mode 100644 app/controllers/movies_controller.rb create mode 100644 test/controllers/customers_controller_test.rb create mode 100644 test/controllers/movies_controller_test.rb diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb new file mode 100644 index 000000000..cddc44ff5 --- /dev/null +++ b/app/controllers/customers_controller.rb @@ -0,0 +1,7 @@ +class CustomersController < ApplicationController + + def index + customers = Customer.all + render json: customers.as_json(except: [:created_at, :updated_at] ) + end +end diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb new file mode 100644 index 000000000..2473b23af --- /dev/null +++ b/app/controllers/movies_controller.rb @@ -0,0 +1,4 @@ +class MoviesController < ApplicationController + + +end diff --git a/config/routes.rb b/config/routes.rb index 787824f88..6899be886 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,6 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + + resources :customers, only: [:index] + resources :movies, only: [:index, :show, :create] end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb new file mode 100644 index 000000000..c9553af67 --- /dev/null +++ b/test/controllers/customers_controller_test.rb @@ -0,0 +1,31 @@ +require "test_helper" + +describe CustomersController do + describe 'index' do + it 'is a working route that sends json' do + get customers_url + + must_respond_with :success + response.header['Content-Type'].must_include 'json' + end + + it 'returns an Array of all the customers' do + get customers_url + + body = JSON.parse(response.body) + body.must_be_kind_of Array + body.length.must_equal Customer.count + end + + it 'returns customers with exactly the required fields' do + keys = %w(address city id name phone postal_code registered_at state) + + get customers_url + + body = JSON.parse(response.body) + body.each do |customer| + customer.keys.sort.must_equal keys + end + end + end +end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb new file mode 100644 index 000000000..67fabbcfb --- /dev/null +++ b/test/controllers/movies_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +describe MoviesController do + # it "must be a real test" do + # flunk "Need real tests" + # end +end From c5c92d85d5ab0334726acbe46b0d2d78c1994cab Mon Sep 17 00:00:00 2001 From: Wenjie Date: Mon, 7 May 2018 15:08:02 -0700 Subject: [PATCH 07/23] Created yml for customers and movies --- test/fixtures/customers.yml | 9 +++++++-- test/fixtures/movies.yml | 12 ++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index dc3ee79b5..8b2dd117c 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -4,8 +4,13 @@ # model remove the "{}" from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # -one: {} +one: + name: tor + phone: 111 111 111 + # column: value # -two: {} +two: + name: wenjie + phone: 222 222 222 # column: value diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index dc3ee79b5..432abcc9d 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -4,8 +4,16 @@ # model remove the "{}" from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # -one: {} +one: + title: harry potter + release_date: <%= Date.new(1996,04,21) %> + overview: Tor loves it! + inventory: 4 # column: value # -two: {} +two: + title: coco + release_date: <%= Date.new(2017,04,21) %> + overview: Wenjie loves it! + inventory: 40 # column: value From 1e48b7578cf96efaa9a573aa9656e144dd2446ee Mon Sep 17 00:00:00 2001 From: Wenjie Date: Mon, 7 May 2018 15:08:50 -0700 Subject: [PATCH 08/23] Added movies controller actions Implemented tests for controller movies, all passed --- app/controllers/customers_controller.rb | 2 +- app/controllers/movies_controller.rb | 33 ++++++++ test/controllers/movies_controller_test.rb | 96 +++++++++++++++++++++- 3 files changed, 127 insertions(+), 4 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index cddc44ff5..19a9d7370 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -2,6 +2,6 @@ class CustomersController < ApplicationController def index customers = Customer.all - render json: customers.as_json(except: [:created_at, :updated_at] ) + render json: customers.as_json(except: [:created_at, :updated_at], status: :ok) end end diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 2473b23af..0febbebac 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -1,4 +1,37 @@ class MoviesController < ApplicationController + def index + movies = Movie.all + render json: movies.as_json(except: [:created_at, :updated_at], status: :ok) + end + def show + movie = Movie.find_by(id: params[:id]) + if movie + render json: movie.as_json(except: [:created_at, :updated_at], status: :ok) + else + render json: { + errors: { + id: ["No movie with ID #{params[:id]}"] + } + }, status: :not_found + end + end + + def create + movie = Movie.new(movie_params) + if movie.save + render json: movie.as_json(except: [:created_at, :updated_at], status: :ok) + else + render json: { + errors: movie.errors.messages + }, status: :bad_request + end + end + + + private + def movie_params + params.require(:movie).permit(:title, :inventory, :release_date, :overview) + end end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 67fabbcfb..1e044b409 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -1,7 +1,97 @@ require "test_helper" describe MoviesController do - # it "must be a real test" do - # flunk "Need real tests" - # end + describe "index" do + it "is a working route that sends json" do + get movies_url + must_respond_with :success + + response.header["Content-Type"].must_include "json" + end + + it "returns an array of all movies" do + get movies_url + body = JSON.parse(response.body) + body.must_be_kind_of Array + body.length.must_equal Movie.count + end + + it "returns movies with exactly the required fields" do + keys = %W[id inventory overview release_date title] + get movies_url + + body = JSON.parse(response.body) + body.each do |movie| + movie.keys.sort.must_equal keys + end + + end + end + + describe "show" do + it "can get a movie" do + keys = %W[id inventory overview release_date title] + + movie_id = movies(:one).id + get movie_url(movie_id) + must_respond_with :success + + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.keys.sort.must_equal keys + body["id"].must_equal movie_id + end + + it "sends a not found status and returns error text if the movie DNE" do + movie_id = Movie.last.id + 1 + get movie_url(movie_id) + must_respond_with :not_found + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "errors" + body["errors"].must_include "id" + end + + end + + describe "create" do + let(:movie_data) { + { + title: "coco", + overview: "great", + release_date: Date.today, + inventory: 100 + } + } + + before do + @before_count = Movie.count + end + + it "can create a new movie" do + post movies_url, params: { + movie: movie_data + } + must_respond_with :success + + Movie.count.must_equal @before_count + 1 + body = JSON.parse(response.body) + body.must_be_kind_of Hash + Movie.find(body["id"]).title.must_equal movie_data[:title] + end + + it "returns an error for invalid movie data" do + movie_data[:title] = "" + + post movies_url, params: { + movie: movie_data + } + must_respond_with :bad_request + Movie.count.must_equal @before_count + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "errors" + body["errors"].must_include "title" + end + end end From 48c4e6e551ea6a794fe492a215a3d89deac2402f Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Mon, 7 May 2018 15:13:37 -0700 Subject: [PATCH 09/23] added a positive case for movie model --- test/models/movie_test.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 9a5f2aa11..04f7c4d8e 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -45,5 +45,16 @@ movie2.valid?.must_equal false movie2.errors.messages.must_include :release_date end + + it 'can be created with sufficient data' do + movie = Movie.new( + title: 'A movie title', + inventory: 1, + release_date: '2018-04-02', + overview: 'great movie' + ) + + movie.valid?.must_equal true + end end end From 16673a19ea2bf049b9328dced7036d0cdd7126fa Mon Sep 17 00:00:00 2001 From: Wenjie Date: Mon, 7 May 2018 15:43:14 -0700 Subject: [PATCH 10/23] Added relations to models --- app/models/customer.rb | 2 ++ app/models/movie.rb | 2 ++ app/models/rental.rb | 2 ++ 3 files changed, 6 insertions(+) diff --git a/app/models/customer.rb b/app/models/customer.rb index bb7ab7822..19c147cec 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -3,6 +3,8 @@ class Customer < ApplicationRecord validates :phone, presence: true validate :same_name_and_same_phone + has_many :rentals + def same_name_and_same_phone customers = Customer.where(name: name) diff --git a/app/models/movie.rb b/app/models/movie.rb index c0ee4b177..3ab51d330 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -3,6 +3,8 @@ class Movie < ApplicationRecord validates :inventory, presence: true, numericality: { only_integer: true, greater_than: 0 } validate :uniq_title_release_date_combo + has_many :rentals + def uniq_title_release_date_combo movies = Movie.where(title: title) diff --git a/app/models/rental.rb b/app/models/rental.rb index 79e3a65ca..e001ff37c 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -1,2 +1,4 @@ class Rental < ApplicationRecord + belongs_to :customer + belongs_to :movie end From 859da326979e04a72acf21d30e031f33c95057b0 Mon Sep 17 00:00:00 2001 From: Wenjie Date: Mon, 7 May 2018 15:43:41 -0700 Subject: [PATCH 11/23] Implemented tests for model relations --- test/models/customer_test.rb | 8 ++++++++ test/models/movie_test.rb | 8 ++++++++ test/models/rental_test.rb | 17 ++++++++++++++--- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 05c608ac9..72cab71a3 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -46,4 +46,12 @@ customer1.errors.messages.must_include :phone end end + + describe 'relations' do + it 'relates rental and rental_id' do + customer = customers(:one) + + customer.rentals.must_include rentals(:one) + end + end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 04f7c4d8e..a805ef7ee 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -57,4 +57,12 @@ movie.valid?.must_equal true end end + + describe 'relations' do + it 'relates rental and rental_id' do + movie = movies(:one) + + movie.rentals.must_include rentals(:one) + end + end end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 6ea53d94f..84e6255d3 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -1,9 +1,20 @@ require "test_helper" describe Rental do - let(:rental) { Rental.new } + + describe "Relations " do + + it "relates movie, movie id, customer and customer id " do + rental = Rental.create( + customer: customers(:two), + movie: movies(:one), + due_date: Date.today + 21 + ) + + rental.movie_id.must_equal movies(:one).id + + rental.customer_id.must_equal customers(:two).id + end - it "must be valid" do - value(rental).must_be :valid? end end From 5e902180fd030561f5bbada76a4b5a20c6dc5730 Mon Sep 17 00:00:00 2001 From: Wenjie Date: Mon, 7 May 2018 15:44:08 -0700 Subject: [PATCH 12/23] Added yml for rentals --- app/controllers/rentals_controller.rb | 2 ++ test/controllers/rentals_controller_test.rb | 7 +++++++ test/fixtures/rentals.yml | 10 ++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 app/controllers/rentals_controller.rb create mode 100644 test/controllers/rentals_controller_test.rb diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb new file mode 100644 index 000000000..58c72b791 --- /dev/null +++ b/app/controllers/rentals_controller.rb @@ -0,0 +1,2 @@ +class RentalsController < ApplicationController +end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb new file mode 100644 index 000000000..f0227216c --- /dev/null +++ b/test/controllers/rentals_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +describe RentalsController do + # it "must be a real test" do + # flunk "Need real tests" + # end +end diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index dc3ee79b5..3efe9f942 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -4,8 +4,14 @@ # model remove the "{}" from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # -one: {} +one: + customer: one + movie: one + due_date: <%= Date.today + 7 %> # column: value # -two: {} +two: + customer: two + movie: two + due_date: <%= Date.today + 10 %> # column: value From 1c0519deb2d454c2fbc76c537f4c749ba3f945ea Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Mon, 7 May 2018 16:29:53 -0700 Subject: [PATCH 13/23] wrote tests for rentals_controller, added conditional validations for rental, wrote tests for additional validations --- app/controllers/rentals_controller.rb | 18 +++++++++ app/models/movie.rb | 5 ++- app/models/rental.rb | 15 ++++++++ config/routes.rb | 3 ++ test/controllers/rentals_controller_test.rb | 41 +++++++++++++++++++-- test/fixtures/movies.yml | 2 +- test/models/rental_test.rb | 29 ++++++++++++++- 7 files changed, 106 insertions(+), 7 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 58c72b791..702030b78 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,2 +1,20 @@ class RentalsController < ApplicationController + def check_out + rental = Rental.new(rental_params) + rental.due_date = Date.today + 7 + + if rental.save + render json: rental.as_json(except: [:updated_at], status: :ok) + else + render json: { + errors: rental.errors.messages + }, status: :bad_request + end + end + + private + + def rental_params + params.require(:rental).permit(:movie_id, :customer_id) + end end diff --git a/app/models/movie.rb b/app/models/movie.rb index 3ab51d330..33bbb536a 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,9 +1,10 @@ class Movie < ApplicationRecord validates :title, presence: true - validates :inventory, presence: true, numericality: { only_integer: true, greater_than: 0 } + validates :inventory, presence: true, numericality: { only_integer: true, greater_than: 0 }, on: :create + validate :uniq_title_release_date_combo - has_many :rentals + has_many :rentals def uniq_title_release_date_combo movies = Movie.where(title: title) diff --git a/app/models/rental.rb b/app/models/rental.rb index e001ff37c..35d62bf82 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -1,4 +1,19 @@ class Rental < ApplicationRecord belongs_to :customer belongs_to :movie + + validates :movie_id, presence: true + validates :customer_id, presence: true + + validate :has_enough_inventory?, if: :movie_id? + + def movie_id? + return self.movie_id + end + + def has_enough_inventory? + unless self.movie.inventory > 0 + errors[:quantity] << 'Not enough inventory for this rental' + end + end end diff --git a/config/routes.rb b/config/routes.rb index 6899be886..1333b3bba 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,4 +3,7 @@ resources :customers, only: [:index] resources :movies, only: [:index, :show, :create] + + post '/rentals/check-out', to: 'rentals#check_out', as: 'check_out' + post '/rentals/check-in', to: 'rentals#check_in', as: 'check_in' end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index f0227216c..7260e1996 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -1,7 +1,42 @@ require "test_helper" describe RentalsController do - # it "must be a real test" do - # flunk "Need real tests" - # end + describe 'check_out' do + before do + @old_rental_count = Rental.count + end + + it 'can create a new rental with good data' do + rental_data = { + movie_id: movies(:one).id, + customer_id: customers(:one).id + } + + post check_out_path, params: { rental: rental_data } + + must_respond_with :success + body = JSON.parse(response.body) + body.must_be_kind_of Hash + Rental.find(body['id']).customer_id.must_equal rental_data[:customer_id] + Rental.count.must_equal @old_rental_count + 1 + end + + it 'returns bad request and error text for bad data' do + rental_data = { + movie_id: movies(:one).id, + } + + post check_out_path, params: { rental: rental_data } + + must_respond_with :bad_request + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include 'errors' + body['errors'].must_include 'customer_id' + + Rental.count.must_equal @old_rental_count + end + end + + end diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index 432abcc9d..ef0b80489 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -8,7 +8,7 @@ one: title: harry potter release_date: <%= Date.new(1996,04,21) %> overview: Tor loves it! - inventory: 4 + inventory: 2 # column: value # two: diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 84e6255d3..d1d919d9a 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -1,7 +1,7 @@ require "test_helper" describe Rental do - + describe "Relations " do it "relates movie, movie id, customer and customer id " do @@ -15,6 +15,33 @@ rental.customer_id.must_equal customers(:two).id end + end + + describe "Validations" do + it 'does not allow you to rent a movie if it does not have enough inventory' do + movie = movies(:one) + customer = customers(:one) + + movie.update(inventory: 0) + + rental3 = Rental.new(movie: movie, customer: customer) + + rental3.valid?.must_equal false + rental3.errors.messages.must_include :quantity + end + + it 'cannot be created without a customer_id' do + rental = Rental.new(movie_id: movies(:one).id) + + rental.valid?.must_equal false + rental.errors.messages.must_include :customer_id + end + + it 'cannot be created without a movie_id' do + rental = Rental.new(customer_id: customers(:one).id) + rental.valid?.must_equal false + rental.errors.messages.must_include :movie_id + end end end From 340a3a02a8a123773ae12f446ab1c5e48961229c Mon Sep 17 00:00:00 2001 From: Wenjie Date: Mon, 7 May 2018 17:06:21 -0700 Subject: [PATCH 14/23] Added a checkout action in rental controller Modified tests for rental controller Added another column in rental model --- app/controllers/rentals_controller.rb | 10 ++++++++++ app/models/movie.rb | 2 +- app/models/rental.rb | 1 + .../20180508000004_add_checkin_and_checkout_date.rb | 5 +++++ db/schema.rb | 3 ++- test/controllers/rentals_controller_test.rb | 6 ++++++ 6 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20180508000004_add_checkin_and_checkout_date.rb diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 702030b78..e1d1afc4a 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -4,6 +4,9 @@ def check_out rental.due_date = Date.today + 7 if rental.save + new_inventory = rental.movie.inventory - 1 + movie = Movie.find(rental.movie_id) + movie.update(inventory: new_inventory) render json: rental.as_json(except: [:updated_at], status: :ok) else render json: { @@ -12,6 +15,13 @@ def check_out end end + def check_in + rental = Rental.find_by() + + end + + + private def rental_params diff --git a/app/models/movie.rb b/app/models/movie.rb index 33bbb536a..ed6290da5 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -2,7 +2,7 @@ class Movie < ApplicationRecord validates :title, presence: true validates :inventory, presence: true, numericality: { only_integer: true, greater_than: 0 }, on: :create - validate :uniq_title_release_date_combo + validate :uniq_title_release_date_combo, on: :create has_many :rentals diff --git a/app/models/rental.rb b/app/models/rental.rb index 35d62bf82..f1a6385b3 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -1,6 +1,7 @@ class Rental < ApplicationRecord belongs_to :customer belongs_to :movie + alias_attribute :created_at, :check_out_date validates :movie_id, presence: true validates :customer_id, presence: true diff --git a/db/migrate/20180508000004_add_checkin_and_checkout_date.rb b/db/migrate/20180508000004_add_checkin_and_checkout_date.rb new file mode 100644 index 000000000..37aabddb6 --- /dev/null +++ b/db/migrate/20180508000004_add_checkin_and_checkout_date.rb @@ -0,0 +1,5 @@ +class AddCheckinAndCheckoutDate < ActiveRecord::Migration[5.1] + def change + add_column :rentals, :check_in_date, :date + end +end diff --git a/db/schema.rb b/db/schema.rb index 162abb345..0f968ea8a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180507194319) do +ActiveRecord::Schema.define(version: 20180508000004) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -42,6 +42,7 @@ t.date "due_date" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.date "check_in_date" t.index ["customer_id"], name: "index_rentals_on_customer_id" t.index ["movie_id"], name: "index_rentals_on_movie_id" end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 7260e1996..6e50f8df6 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -11,10 +11,13 @@ movie_id: movies(:one).id, customer_id: customers(:one).id } + movie_inventory = movies(:one).inventory post check_out_path, params: { rental: rental_data } must_respond_with :success + movies(:one).reload + movies(:one).inventory.must_equal movie_inventory - 1 body = JSON.parse(response.body) body.must_be_kind_of Hash Rental.find(body['id']).customer_id.must_equal rental_data[:customer_id] @@ -25,10 +28,13 @@ rental_data = { movie_id: movies(:one).id, } + movie_inventory = movies(:one).inventory post check_out_path, params: { rental: rental_data } must_respond_with :bad_request + movies(:one).inventory.must_equal movie_inventory + body = JSON.parse(response.body) body.must_be_kind_of Hash body.must_include 'errors' From 6df4de1c47ccc7ffee99cd44f0df08af39c4cf6f Mon Sep 17 00:00:00 2001 From: Wenjie Date: Tue, 8 May 2018 14:14:32 -0700 Subject: [PATCH 15/23] Added available inventory column to movies and movies checkout count column for customers --- app/controllers/movies_controller.rb | 3 ++- app/controllers/rentals_controller.rb | 4 ++-- app/models/rental.rb | 2 +- db/migrate/20180508210830_add_available_inventory_column.rb | 5 +++++ db/migrate/20180508210946_add_checked_out_movies_column.rb | 5 +++++ db/schema.rb | 4 +++- 6 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20180508210830_add_available_inventory_column.rb create mode 100644 db/migrate/20180508210946_add_checked_out_movies_column.rb diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 0febbebac..efe427281 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -19,6 +19,7 @@ def show def create movie = Movie.new(movie_params) + movie.available_inventory = movie.inventory if movie.save render json: movie.as_json(except: [:created_at, :updated_at], status: :ok) else @@ -31,7 +32,7 @@ def create private def movie_params - params.require(:movie).permit(:title, :inventory, :release_date, :overview) + params.permit(:title, :inventory, :release_date, :overview) end end diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index e1d1afc4a..a922b5b8d 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -4,9 +4,9 @@ def check_out rental.due_date = Date.today + 7 if rental.save - new_inventory = rental.movie.inventory - 1 + new_inventory = rental.movie.available_inventory - 1 movie = Movie.find(rental.movie_id) - movie.update(inventory: new_inventory) + movie.update(available_inventory: new_inventory) render json: rental.as_json(except: [:updated_at], status: :ok) else render json: { diff --git a/app/models/rental.rb b/app/models/rental.rb index f1a6385b3..77a78ac14 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -13,7 +13,7 @@ def movie_id? end def has_enough_inventory? - unless self.movie.inventory > 0 + unless self.movie.available_inventory > 0 errors[:quantity] << 'Not enough inventory for this rental' end end diff --git a/db/migrate/20180508210830_add_available_inventory_column.rb b/db/migrate/20180508210830_add_available_inventory_column.rb new file mode 100644 index 000000000..629218ee7 --- /dev/null +++ b/db/migrate/20180508210830_add_available_inventory_column.rb @@ -0,0 +1,5 @@ +class AddAvailableInventoryColumn < ActiveRecord::Migration[5.1] + def change + add_column :movies, :available_inventory, :integer + end +end diff --git a/db/migrate/20180508210946_add_checked_out_movies_column.rb b/db/migrate/20180508210946_add_checked_out_movies_column.rb new file mode 100644 index 000000000..bdce5dafc --- /dev/null +++ b/db/migrate/20180508210946_add_checked_out_movies_column.rb @@ -0,0 +1,5 @@ +class AddCheckedOutMoviesColumn < ActiveRecord::Migration[5.1] + def change + add_column :customers, :movies_checked_out_count, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 0f968ea8a..4c33a961a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180508000004) do +ActiveRecord::Schema.define(version: 20180508210946) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -25,6 +25,7 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.datetime "registered_at" + t.integer "movies_checked_out_count" end create_table "movies", force: :cascade do |t| @@ -34,6 +35,7 @@ t.integer "inventory" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "available_inventory" end create_table "rentals", force: :cascade do |t| From 08f4df047f78fac023fda0f8f3e5c0e8b6ec9252 Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Tue, 8 May 2018 14:29:38 -0700 Subject: [PATCH 16/23] updated inventory to available inventory. removed required :movie from strong params --- app/models/rental.rb | 2 +- test/controllers/customers_controller_test.rb | 2 +- test/controllers/movies_controller_test.rb | 8 +++----- test/controllers/rentals_controller_test.rb | 4 ++-- test/fixtures/movies.yml | 2 ++ test/models/rental_test.rb | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/models/rental.rb b/app/models/rental.rb index 77a78ac14..b6909aac6 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -1,7 +1,7 @@ class Rental < ApplicationRecord belongs_to :customer belongs_to :movie - alias_attribute :created_at, :check_out_date + # alias_attribute :created_at, :check_out_date validates :movie_id, presence: true validates :customer_id, presence: true diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index c9553af67..ab62d6b0c 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -18,7 +18,7 @@ end it 'returns customers with exactly the required fields' do - keys = %w(address city id name phone postal_code registered_at state) + keys = %w(address city id movies_checked_out_count name phone postal_code registered_at state) get customers_url diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 1e044b409..05b3b2abe 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -17,7 +17,7 @@ end it "returns movies with exactly the required fields" do - keys = %W[id inventory overview release_date title] + keys = %W[available_inventory id inventory overview release_date title] get movies_url body = JSON.parse(response.body) @@ -30,7 +30,7 @@ describe "show" do it "can get a movie" do - keys = %W[id inventory overview release_date title] + keys = %W[available_inventory id inventory overview release_date title] movie_id = movies(:one).id get movie_url(movie_id) @@ -69,9 +69,7 @@ end it "can create a new movie" do - post movies_url, params: { - movie: movie_data - } + post movies_url, params: movie_data must_respond_with :success Movie.count.must_equal @before_count + 1 diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 6e50f8df6..e07861e27 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -11,13 +11,13 @@ movie_id: movies(:one).id, customer_id: customers(:one).id } - movie_inventory = movies(:one).inventory + movie_inventory = movies(:one).available_inventory post check_out_path, params: { rental: rental_data } must_respond_with :success movies(:one).reload - movies(:one).inventory.must_equal movie_inventory - 1 + movies(:one).available_inventory.must_equal movie_inventory - 1 body = JSON.parse(response.body) body.must_be_kind_of Hash Rental.find(body['id']).customer_id.must_equal rental_data[:customer_id] diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index ef0b80489..23419e4a0 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -9,6 +9,7 @@ one: release_date: <%= Date.new(1996,04,21) %> overview: Tor loves it! inventory: 2 + available_inventory: 2 # column: value # two: @@ -16,4 +17,5 @@ two: release_date: <%= Date.new(2017,04,21) %> overview: Wenjie loves it! inventory: 40 + available_inventory: 2 # column: value diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index d1d919d9a..cfd2cd552 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -22,7 +22,7 @@ movie = movies(:one) customer = customers(:one) - movie.update(inventory: 0) + movie.update(available_inventory: 0) rental3 = Rental.new(movie: movie, customer: customer) From d8c34f9df697a7704fb41e5369ffb1725ef5a8d5 Mon Sep 17 00:00:00 2001 From: Wenjie Date: Tue, 8 May 2018 14:56:28 -0700 Subject: [PATCH 17/23] Added business logic to rental model Implemented tests for business logic --- app/controllers/rentals_controller.rb | 2 +- app/models/rental.rb | 5 +++++ test/fixtures/rentals.yml | 2 ++ test/models/rental_test.rb | 21 +++++++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index a922b5b8d..e4ea07565 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -16,7 +16,7 @@ def check_out end def check_in - rental = Rental.find_by() + end diff --git a/app/models/rental.rb b/app/models/rental.rb index b6909aac6..5d3215d6d 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -17,4 +17,9 @@ def has_enough_inventory? errors[:quantity] << 'Not enough inventory for this rental' end end + + def self.find_checked_out_movie(movie_id, customer_id) + rental = Rental.where(movie_id: movie_id, customer_id: customer_id, check_in_date: nil) + return rental.empty? ? nil : rental.first + end end diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 3efe9f942..f37a47379 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -8,10 +8,12 @@ one: customer: one movie: one due_date: <%= Date.today + 7 %> + check_in_date: # column: value # two: customer: two movie: two due_date: <%= Date.today + 10 %> + check_in_date: # column: value diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index cfd2cd552..6012f466e 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -44,4 +44,25 @@ rental.errors.messages.must_include :movie_id end end + + describe "business logic" do + describe "find_checked_out_movie" do + it "returns a checked out rental" do + rental = rentals(:one) + movie_id = rental.movie_id + customer_id = rental.customer_id + result = Rental.find_checked_out_movie(movie_id, customer_id) + result.must_be_kind_of Rental + result.must_equal rental + end + + it "returns nil if the rental DNE" do + rental = rentals(:one) + movie_id = rental.movie_id + 100 + customer_id = rental.customer_id + result = Rental.find_checked_out_movie(movie_id, customer_id) + result.must_be_nil + end + end + end end From 2c228ead045049973f4554370fffbd0733eec83e Mon Sep 17 00:00:00 2001 From: Wenjie Date: Tue, 8 May 2018 15:15:35 -0700 Subject: [PATCH 18/23] Added check out action for rentals controller --- app/controllers/rentals_controller.rb | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index e4ea07565..03aa0eeec 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -9,14 +9,22 @@ def check_out movie.update(available_inventory: new_inventory) render json: rental.as_json(except: [:updated_at], status: :ok) else - render json: { - errors: rental.errors.messages - }, status: :bad_request + render json: { errors: rental.errors.messages}, status: :bad_request end end def check_in - + rental = Rental.find_checked_out_movie(params[:movie_id], params[:customer_id]) + if rental + rental.update(check_in_date: Date.today) + render json: rental.as_json(except: [:updated_at], status: :ok) + else + render json: { + errors: { + rental: ["No rental found"] + } + } + end end @@ -25,6 +33,6 @@ def check_in private def rental_params - params.require(:rental).permit(:movie_id, :customer_id) + params.permit(:movie_id, :customer_id) end end From 2f1a35585195163d7516fc5e690126e0e24deca1 Mon Sep 17 00:00:00 2001 From: Wenjie Date: Tue, 8 May 2018 15:38:01 -0700 Subject: [PATCH 19/23] Implemented tests for rentals check in --- app/controllers/rentals_controller.rb | 5 ++- app/models/movie.rb | 2 +- db/seeds.rb | 3 +- test/controllers/rentals_controller_test.rb | 42 ++++++++++++++++++++- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 03aa0eeec..a6adc7fe5 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -17,13 +17,16 @@ def check_in rental = Rental.find_checked_out_movie(params[:movie_id], params[:customer_id]) if rental rental.update(check_in_date: Date.today) + new_inventory = rental.movie.available_inventory + 1 + movie = Movie.find(rental.movie_id) + movie.update(available_inventory: new_inventory) render json: rental.as_json(except: [:updated_at], status: :ok) else render json: { errors: { rental: ["No rental found"] } - } + }, status: :not_found end end diff --git a/app/models/movie.rb b/app/models/movie.rb index ed6290da5..b61dcb3f7 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,6 +1,6 @@ class Movie < ApplicationRecord validates :title, presence: true - validates :inventory, presence: true, numericality: { only_integer: true, greater_than: 0 }, on: :create + validates :inventory, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, on: :create validate :uniq_title_release_date_combo, on: :create diff --git a/db/seeds.rb b/db/seeds.rb index 5322340ba..e20b4e4cf 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -3,5 +3,6 @@ end JSON.parse(File.read('db/seeds/movies.json')).each do |movie| - Movie.create!(movie) + m = Movie.create!(movie) + m.update(available_inventory: m.inventory) end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index e07861e27..a01b8b46f 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -13,7 +13,7 @@ } movie_inventory = movies(:one).available_inventory - post check_out_path, params: { rental: rental_data } + post check_out_path, params: rental_data must_respond_with :success movies(:one).reload @@ -30,7 +30,7 @@ } movie_inventory = movies(:one).inventory - post check_out_path, params: { rental: rental_data } + post check_out_path, params: rental_data must_respond_with :bad_request movies(:one).inventory.must_equal movie_inventory @@ -44,5 +44,43 @@ end end + describe "check_in" do + it "checks in a rental" do + rental = rentals(:one) + rental_data = { + movie_id: rental.movie_id, + customer_id: rental.customer_id + } + + movie_inventory = rental.movie.available_inventory + + post check_in_path, params: rental_data + + must_respond_with :success + movies(:one).reload + movies(:one).available_inventory.must_equal movie_inventory + 1 + body = JSON.parse(response.body) + body.must_be_kind_of Hash + Rental.find(body['id']).check_in_date.must_equal Date.today + + end + + it "return bad request and error if the rental DNE" do + rental = rentals(:one) + rental_data = { + movie_id: rental.movie_id + 100, + customer_id: rental.customer_id + } + + post check_in_path, params: rental_data + + must_respond_with :not_found + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include 'errors' + body['errors'].must_include 'rental' + end + end + end From 562ef6a19765f83522fc61bdcf350c76d49a4420 Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Tue, 8 May 2018 16:24:17 -0700 Subject: [PATCH 20/23] Fixed validation bug and made all tests passed --- app/controllers/rentals_controller.rb | 10 ++++++++++ app/models/customer.rb | 2 +- ...4_add_default_to_movies_checked_out_count.rb | 5 +++++ db/schema.rb | 4 ++-- test/controllers/rentals_controller_test.rb | 17 +++++++++++------ 5 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 db/migrate/20180508224654_add_default_to_movies_checked_out_count.rb diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index a6adc7fe5..d5e34682f 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -7,6 +7,11 @@ def check_out new_inventory = rental.movie.available_inventory - 1 movie = Movie.find(rental.movie_id) movie.update(available_inventory: new_inventory) + + new_count = rental.customer.movies_checked_out_count + 1 + customer = Customer.find_by(id: rental.customer_id) + customer.update(movies_checked_out_count: new_count) + render json: rental.as_json(except: [:updated_at], status: :ok) else render json: { errors: rental.errors.messages}, status: :bad_request @@ -19,6 +24,11 @@ def check_in rental.update(check_in_date: Date.today) new_inventory = rental.movie.available_inventory + 1 movie = Movie.find(rental.movie_id) + + new_count = rental.customer.movies_checked_out_count - 1 + customer = Customer.find_by(id: rental.customer_id) + customer.update(movies_checked_out_count: new_count) + movie.update(available_inventory: new_inventory) render json: rental.as_json(except: [:updated_at], status: :ok) else diff --git a/app/models/customer.rb b/app/models/customer.rb index 19c147cec..c003a404e 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,7 +1,7 @@ class Customer < ApplicationRecord validates :name, presence: true validates :phone, presence: true - validate :same_name_and_same_phone + validate :same_name_and_same_phone, on: :create has_many :rentals diff --git a/db/migrate/20180508224654_add_default_to_movies_checked_out_count.rb b/db/migrate/20180508224654_add_default_to_movies_checked_out_count.rb new file mode 100644 index 000000000..081b5c288 --- /dev/null +++ b/db/migrate/20180508224654_add_default_to_movies_checked_out_count.rb @@ -0,0 +1,5 @@ +class AddDefaultToMoviesCheckedOutCount < ActiveRecord::Migration[5.1] + def change + change_column_default :customers, :movies_checked_out_count, 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 4c33a961a..7c2f6c71c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180508210946) do +ActiveRecord::Schema.define(version: 20180508224654) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -25,7 +25,7 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.datetime "registered_at" - t.integer "movies_checked_out_count" + t.integer "movies_checked_out_count", default: 0 end create_table "movies", force: :cascade do |t| diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index a01b8b46f..fd1c947a7 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -46,23 +46,28 @@ describe "check_in" do it "checks in a rental" do - rental = rentals(:one) rental_data = { - movie_id: rental.movie_id, - customer_id: rental.customer_id + movie_id: Movie.first.id, + customer_id: Customer.first.id } + post check_out_path, params: rental_data + + rental = Rental.last + movie_inventory = rental.movie.available_inventory + customer_movie_count = rental.customer.movies_checked_out_count post check_in_path, params: rental_data must_respond_with :success - movies(:one).reload - movies(:one).available_inventory.must_equal movie_inventory + 1 + rental.reload + rental.movie.available_inventory.must_equal movie_inventory + 1 + rental.customer.movies_checked_out_count.must_equal customer_movie_count - 1 + body = JSON.parse(response.body) body.must_be_kind_of Hash Rental.find(body['id']).check_in_date.must_equal Date.today - end it "return bad request and error if the rental DNE" do From 5cc36deb7622f5d9b7603dda5f39af073dbce9bb Mon Sep 17 00:00:00 2001 From: Wenjie Date: Tue, 8 May 2018 16:29:23 -0700 Subject: [PATCH 21/23] Added ERD for this project --- VideoStoreAPI.jpeg | Bin 0 -> 33224 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 VideoStoreAPI.jpeg diff --git a/VideoStoreAPI.jpeg b/VideoStoreAPI.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..848739bba315390151f644819d5caec65d5cbe89 GIT binary patch literal 33224 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 Date: Wed, 9 May 2018 09:18:00 -0700 Subject: [PATCH 22/23] moving updating rental movie and customer inventory to rental model --- app/controllers/rentals_controller.rb | 34 ++++++++++++++------------- app/models/rental.rb | 19 +++++++++++++++ 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index d5e34682f..4e633774c 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -4,14 +4,15 @@ def check_out rental.due_date = Date.today + 7 if rental.save - new_inventory = rental.movie.available_inventory - 1 - movie = Movie.find(rental.movie_id) - movie.update(available_inventory: new_inventory) - - new_count = rental.customer.movies_checked_out_count + 1 - customer = Customer.find_by(id: rental.customer_id) - customer.update(movies_checked_out_count: new_count) - + # new_inventory = rental.movie.available_inventory - 1 + # movie = Movie.find(rental.movie_id) + # movie.update(available_inventory: new_inventory) + # + # new_count = rental.customer.movies_checked_out_count + 1 + # customer = Customer.find_by(id: rental.customer_id) + # customer.update(movies_checked_out_count: new_count) + + rental = Rental.update_movie_and_customer(rental) render json: rental.as_json(except: [:updated_at], status: :ok) else render json: { errors: rental.errors.messages}, status: :bad_request @@ -21,14 +22,15 @@ def check_out def check_in rental = Rental.find_checked_out_movie(params[:movie_id], params[:customer_id]) if rental - rental.update(check_in_date: Date.today) - new_inventory = rental.movie.available_inventory + 1 - movie = Movie.find(rental.movie_id) - - new_count = rental.customer.movies_checked_out_count - 1 - customer = Customer.find_by(id: rental.customer_id) - customer.update(movies_checked_out_count: new_count) - + # rental.update(check_in_date: Date.today) + # new_inventory = rental.movie.available_inventory + 1 + # movie = Movie.find(rental.movie_id) + # + # new_count = rental.customer.movies_checked_out_count - 1 + # customer = Customer.find_by(id: rental.customer_id) + # customer.update(movies_checked_out_count: new_count) + + rental = Rental.update_movie_and_customer(rental) movie.update(available_inventory: new_inventory) render json: rental.as_json(except: [:updated_at], status: :ok) else diff --git a/app/models/rental.rb b/app/models/rental.rb index 5d3215d6d..6f1d5c6ad 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -22,4 +22,23 @@ def self.find_checked_out_movie(movie_id, customer_id) rental = Rental.where(movie_id: movie_id, customer_id: customer_id, check_in_date: nil) return rental.empty? ? nil : rental.first end + + + def self.update_movie_and_customer(rental) + + if rental.check_in_date.nil? + new_inventory = rental.movie.available_inventory - 1 + new_count = rental.customer.movies_checked_out_count + 1 + else + new_inventory = rental.movie.available_inventory + 1 + new_count = rental.customer.movies_checked_out_count - 1 + end + # do we need to rescue this error if there is one? + # movie = Movie.find_by(id: rental.movie_id) + rental.movie.update(available_inventory: new_inventory) + + rental.customer.update(movies_checked_out_count: new_count) + + return rental + end end From d09a9ad4f8abef18305d417fa066fd103034e6db Mon Sep 17 00:00:00 2001 From: Tor Shimizu Date: Wed, 9 May 2018 09:35:04 -0700 Subject: [PATCH 23/23] moved updating customer movies_checked_in_count and movie available inventory and wrote model tests --- app/controllers/rentals_controller.rb | 18 +---------------- app/models/rental.rb | 9 ++++----- test/models/rental_test.rb | 28 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 4e633774c..ad89eca49 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -4,14 +4,6 @@ def check_out rental.due_date = Date.today + 7 if rental.save - # new_inventory = rental.movie.available_inventory - 1 - # movie = Movie.find(rental.movie_id) - # movie.update(available_inventory: new_inventory) - # - # new_count = rental.customer.movies_checked_out_count + 1 - # customer = Customer.find_by(id: rental.customer_id) - # customer.update(movies_checked_out_count: new_count) - rental = Rental.update_movie_and_customer(rental) render json: rental.as_json(except: [:updated_at], status: :ok) else @@ -22,16 +14,8 @@ def check_out def check_in rental = Rental.find_checked_out_movie(params[:movie_id], params[:customer_id]) if rental - # rental.update(check_in_date: Date.today) - # new_inventory = rental.movie.available_inventory + 1 - # movie = Movie.find(rental.movie_id) - # - # new_count = rental.customer.movies_checked_out_count - 1 - # customer = Customer.find_by(id: rental.customer_id) - # customer.update(movies_checked_out_count: new_count) - + rental.update(check_in_date: Date.today) rental = Rental.update_movie_and_customer(rental) - movie.update(available_inventory: new_inventory) render json: rental.as_json(except: [:updated_at], status: :ok) else render json: { diff --git a/app/models/rental.rb b/app/models/rental.rb index 6f1d5c6ad..e7d03a120 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -33,12 +33,11 @@ def self.update_movie_and_customer(rental) new_inventory = rental.movie.available_inventory + 1 new_count = rental.customer.movies_checked_out_count - 1 end - # do we need to rescue this error if there is one? - # movie = Movie.find_by(id: rental.movie_id) - rental.movie.update(available_inventory: new_inventory) - rental.customer.update(movies_checked_out_count: new_count) + rental.movie.update(available_inventory: new_inventory) - return rental + rental.customer.update(movies_checked_out_count: new_count) + + return rental end end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 6012f466e..851e7ca6a 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -64,5 +64,33 @@ result.must_be_nil end end + + describe 'update_movie_and_customer' do + it 'updates movie and customer inventory/counts during checkout' do + rental = Rental.first + movie_available_inventory = rental.movie.available_inventory + customer_movies_count = rental.customer.movies_checked_out_count + + result = Rental.update_movie_and_customer(rental) + + result.must_equal rental + result.movie.available_inventory.must_equal movie_available_inventory - 1 + result.customer.movies_checked_out_count.must_equal customer_movies_count + 1 + end + + it 'updates movie and customer inventory/counts during checkin' do + rental = Rental.first + rental.update(check_in_date: Date.today) + + movie_available_inventory = rental.movie.available_inventory + customer_movies_count = rental.customer.movies_checked_out_count + + result = Rental.update_movie_and_customer(rental) + + result.must_equal rental + result.movie.available_inventory.must_equal movie_available_inventory + 1 + result.customer.movies_checked_out_count.must_equal customer_movies_count - 1 + end + end end end