-
Notifications
You must be signed in to change notification settings - Fork 25
Sam & Hannah -- Octos #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
786aa86
f3beb43
1886154
2e52676
3421d2d
d659e74
d9e2415
625a9a5
45fcc91
cbc6002
41168b6
77e01eb
f0987f0
22c1bf7
9f94646
0f98b40
aed9342
0862448
b5e7826
eac8b4b
4470c5e
6f69770
56339d6
bd9dc0a
826af96
7dabaeb
eeefb89
b5ca545
53b18ab
4b66bbe
63cc4c3
0b66246
8eebda3
5ae0389
a30a031
ff12a1b
019c22b
63d446f
8098059
0af344a
5148b7f
6f78be5
244e3ca
1c6de97
494b63c
15408d2
25264f8
19dfd05
bd13df2
d6ba637
d2a3620
bbfec9f
8670626
06c4359
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| module ApplicationCable | ||
| class Channel < ActionCable::Channel::Base | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| module ApplicationCable | ||
| class Connection < ActionCable::Connection::Base | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| class ApplicationController < ActionController::API | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| class CustomersController < ApplicationController | ||
|
|
||
| def index | ||
| customers = Customer.all | ||
| render json: customers.as_json(only: [:id, :movies_checked_out_count, :name, :phone, :postal_code, :registered_at]), status: :ok | ||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| class MoviesController < ApplicationController | ||
|
|
||
| def index | ||
| movies = Movie.all | ||
| render json: movies.as_json(only: [:id, :title, :release_date]), status: :ok | ||
| end | ||
|
|
||
| def show | ||
| movie = Movie.find_by(id: params[:id]) | ||
| if movie.nil? | ||
| render json: { errors: "Movie with id #{params[:id]}does not exist" }, status: :not_found | ||
| else | ||
| render json: movie.as_json(only: [:title, :overview, :release_date, :inventory, :available_inventory]), status: :ok | ||
| end | ||
| end | ||
|
|
||
| def create | ||
| movie = Movie.new(movie_params) | ||
|
|
||
| if movie.save | ||
| render json: { id: movie.id }, status: :ok | ||
| else | ||
| render json: { errors: movie.errors.messages }, status: :bad_request | ||
| end | ||
|
|
||
| end | ||
|
|
||
| private | ||
|
|
||
| def movie_params | ||
| return params.require(:movie).permit(:title, :overview, :release_date, :inventory) | ||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| class RentalsController < ApplicationController | ||
|
|
||
| def create | ||
| rental = Rental.new(rental_params) | ||
|
|
||
| movie = Movie.find_by(id: rental_params[:movie_id]) | ||
| customer = Customer.find_by(id: rental_params[:customer_id]) | ||
|
|
||
| if movie.nil? | ||
| render json: {errors: "Movie with id #{rental_params[:movie_id]} doesn't exist"}, status: :bad_request | ||
| return | ||
| end | ||
|
|
||
| if movie.available_inventory == 0 | ||
| render json: { errors: "No available inventory for #{movie.title}." }, status: :bad_request | ||
| return | ||
| end | ||
|
|
||
| if rental.save | ||
| movie.decrement_available_inventory | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be logical to move all of this updating logic into a rental model method. One thing to keep in mind in the future is that when an action requires many model updates, you may want to combine these into a transaction. If the rental save succeeds, then you also want to ensure that the movie and customer object updates work, otherwise you could end up in an odd state where the movie inventory is updated, but the customer's isn't. |
||
| movie.save | ||
| customer.increment_movies_checked_out_count | ||
| customer.save | ||
| render json: { id: rental.id, due_date: rental.due_date }, status: :ok | ||
| else | ||
| render json: { errors: rental.errors.messages }, status: :bad_request | ||
| end | ||
|
|
||
| end | ||
|
|
||
| def update | ||
| rental = Rental.find_by(rental_params) | ||
| if rental.nil? | ||
| render json: { errors: "This rental does not exist." }, status: :bad_request | ||
| return | ||
| end | ||
|
|
||
| movie = rental.movie | ||
| customer = rental.customer | ||
|
|
||
| if rental.updated_at != rental.created_at | ||
| render json: { errors: "#{movie.title} is already checked-in." }, status: :bad_request | ||
| else | ||
| if rental.save | ||
| movie.increment_available_inventory | ||
| movie.save | ||
| customer.decrement_movies_checked_out_count | ||
| customer.save | ||
| render json: { id: rental.id, "check-in date": rental.updated_at }, status: :ok | ||
| else | ||
| render json: { errors: rental.errors.messages }, status: :bad_request | ||
| end | ||
| end | ||
|
|
||
| end | ||
|
|
||
| private | ||
| def rental_params | ||
| return params.require(:rental).permit(:movie_id, :customer_id) | ||
| end | ||
|
|
||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| class ApplicationJob < ActiveJob::Base | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| class ApplicationMailer < ActionMailer::Base | ||
| default from: 'from@example.com' | ||
| layout 'mailer' | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| class ApplicationRecord < ActiveRecord::Base | ||
| self.abstract_class = true | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| class Customer < ApplicationRecord | ||
| has_many :rentals | ||
| has_many :movies, through: :rentals | ||
|
|
||
| validates :name, presence: true | ||
| validates :movies_checked_out_count, presence: true, numericality: { only_integer: true } | ||
|
|
||
| def decrement_movies_checked_out_count | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it known that this will do nothing if there aren't any checked out? |
||
| if self.movies_checked_out_count > 0 | ||
| self.movies_checked_out_count -= 1 | ||
| end | ||
| end | ||
|
|
||
| def increment_movies_checked_out_count | ||
| self.movies_checked_out_count += 1 | ||
| end | ||
|
|
||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the customer doesn't exist?