Your local environment supports the following:
- PostgreSQL (9.3 version or newer)
- Rails 7.0
- Ruby 2.7.0 (required by Rails 7.0)
Assuming you have all the prerequisites installed:
- Git clone the repo
- Change to the project directory:
cd jurassic_park
- Install the required gems:
bundle install
- Create the database:
rails db:create
- Run the database migrations:
rails db:migrate
- Seed the database:
rails db:seed
- Start the Rails server:
rails server
- Open one of following endpoints:
/dinosaurs
,/cages
,/species
.
You can also use filtering options with endpoints:
- caged
- not_caged
- carnivore
- herbivore
- Species, by name - for example Tyrannosaurus
- Mix of filters: not_caged carnivore
- empty
- full
- not_full
- not_empty
- active
- down
- Mix of filters: not_full not_empty (ie: partially filled cages)
- First and foremost: In practice, I would have seeked clarification on requirements with the product manager, so that way we all know what we're expecting in the deliverables - for example some of the assumptions I will discuss below (dinosaurs can be uncaged, etc)
- 100% Rspec & Rubocop: I did exclude some files for Rubocop, as well as disabling certain cops in specific places, but for most part I think we're in a good place here.
- Dinosaurs can be uncaged: What if there was an incident and a dinosaur has escaped a cage? Or a dinosaur is currently being treated by a vet? Or has deceased, but we still want to keep a database record of, in memorandum? The assessment made no explicit mention that dinosaurs must be "caged".
- Cages could have capacity changed: "Cages" to me could be anything - it could be an outdoors enclosure with electrical fencing boundary. Maybe later the aforementioned enclosure is expanded (take over more land) to hold more dinosaurs? I allowed for this possibility.
- Dinosaur names must be unique: Prevents "Oops, you mean Charlie the herbivore? I thought you were referring to Charlie the carnivore? Oh no, I just uncaged Charlie the herbivore into general area with other carnivores.." type of situation.
- "Dinosaur type" (carnivore vs herbivore) is a property inherent to "species": The way I saw it, "carnivore" or "herbivore" is something that I feel should be assigned to "species", so I decided to split off a separate "Species" model, with it own enum for dinosaur type (carnivore vs herbivore). I do realize I might have inadvertently created more work for myself for an assessment. If I had more times I would probably explore for ways to have the "species" + "dinosaur type" enum as part of "Dinosaur" class.
- How I would have addressed concurrency concerns: Database constraints (checks and triggers). Those db constraints would prevent race conditions where things might happen where it should not (ie: application logic, because of concurrent requests somehow accidentally place herbivores and carnivores togehter in a cage). Utilize background workers (like Sidekiq) to handle updates.