Skip to content

Conversation

@kaganon
Copy link

@kaganon kaganon commented Nov 9, 2018

Video Store API

Congratulations! You're submitting your assignment!
If you didn't get to the functionality the question is asking about, reply with what you would have done if you had completed it.

Comprehension Questions

Question Answer
Explain how you came up with the design of your ERD, based on the seed data. At first we did a join table for customers_movies, but then we dropped the table and created a model with foreign_keys of movies and customers. We also added a column for check_out date, due_date, and checkin_date for the rental model.
What would be the Big-O time complexity of your /customers & /movies endpoints? What does the time complexity depend on? Explain your reasoning. It's O(n) linear because it needs to iterate through the entire collection of customers or movies in order to display all customers/movies.
What is the Big-O time complexity of the POST /rentals/check-in endpoint? What does the time complexity depend on? Explain your reasoning. Assuming that the find-by method works by iterating through the entire array to find the id... it's O(3n) because you are iterating through the three arrays of each customer, movie, and rental to find the associated matching rental id.
Describe a set of positive and negative test cases you implemented for a model. For movie model, we tested that it returns the available inventory if there are inventory available, and it returns 0 if there are no available inventory/all movies are checked out .
Describe a set of positive and negative test cases you implemented for a controller. For positive case: if there are no rentals matching, it renders an error. Otherwise, it creates a rental and returns the JSON with a rental id with valid input.
How does your API respond when bad data is sent to it? It responds by displaying the errors that need to be corrected to the user.
Describe one of your custom model methods and why you chose to wrap that functionality into a method. We did a custom method for counting the movies_checkout out_count for a customer. It performs an active record search, and counts all the rentals where the check_in date is nil (which from the way we wrote our code means that the movies have been checked out). We chose to wrap this in a method because we can take advantage of the has-many and belongs to relationship with the customer/rentals.
Do you have any recommendations on how we could improve this project for the next cohort? It was nice having this project as an end to our Rails chapter! :)
Link to Trello https://trello.com/b/vFCaXA1J/amber-lynn-katrina
Link to ERD https://www.lucidchart.com/documents/edit/4da7a5d8-fa52-4d3b-9fad-7e35b127ef44/0
Summary :)

kaganon and others added 30 commits November 5, 2018 12:16
@Hamled
Copy link

Hamled commented Nov 19, 2018

Video Store

What We're Looking For

Feature Feedback
Core Requirements
Git hygiene
Comprehension questions
Note: For the Big-O question about the /rentals/check-in route... O(3n) is the same as O(n) because we ignore coefficients when dealing with Big-O complexity categories.
General
Business Logic in Models Mostly.
Y'all did a great job of creating "attribute" methods in the model classes, like movies_checked_out_count and is_available?. However I think even more logic from the RentalsController#checkin and checkout actions could be moved into the model.
All required endpoints return expected JSON data
Requests respond with appropriate HTTP Status Code
Errors are reported
Testing
Passes all Smoke Tests
Model Tests - all relations, validations, and custom functions test positive & negative cases
Controller Tests - URI parameters and data in the request body have positive & negative cases
Overall Great work on this project!


def find_rental(movie)
self.rentals.each do |rental|
return rental if rental.movie == movie
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be simplified to:

def find_rental(movie)
  self.rentals.find_by(movie: movie) || false
end

end

def movies_checked_out_count
return self.rentals.where(checkin_date: nil).count
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent use of ActiveRecord methods!


def is_available?
return self.movie.available_inventory > 0 if self.movie
return false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor quibble, but I think the logic here would be more clear in the opposite order:

def is_available?
  return false unless self.movie

  self.movie.available_inventory > 0
end


it "renders bad_request status code and returns JSON with error messages if the rental was not successfully saved" do

# QUESTION: not sure how to setup the controller test and make saving the rental fail. Checkout date and due date is not a required validation until trying to save upon checkout. The rental.save method would fail if checkout_date and due_date somehow returns nil or false upon checkout, and therefore return the error messages...but this is difficult to test in the controller tests using the post checkout_path bc valid params would always save the rental.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is a difficult one. I actually think this question could be answered by reconsidering how we define different error responses.

Right now we're trying to use a 400 Bad Request response to indicate that we weren't able to successfully save the Rental model with the check-in date. This makes sense, because we've only ever written code to handle saving failures as Bad Request.

However, that's not because Bad Request is inherently the correct response code when we fail to save to the database. It's because in those previous cases we were anticipating the failure was a result of validation errors -- ultimately due to bad data from the user.

In this case we can be pretty certain from the controller code, that the save would never fail due to validations (the only validations are "presence" for attributes which we explicitly set with values not derived from user data). As such, Bad Request is not the correct response for that case.

Instead, I would argue that a 500 Internal Server Error is the correct response code for that case. It's generally never a good thing to return a 500, usually it means there was an error that got raised but was never rescued. And that's pretty much the scenario we're in with this action.

Saving the Rental model to the database should never fail under any expected circumstances, so the only situations where it would fail are inherently exceptional (e.g. the database server is unreachable or cannot store more data).

It's probably possible to design a test to trigger one of these cases and verify that a 500 response is send back, but:

  • the logic for doing that is actually part of Rails and not any code we've written ourselves
  • it is, by definition, an unpredictable situation... so it's probably not worth building a specific test case for

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants