In this assignment we will be creating an application to look up farmers markets and their related vendors, products, and sales. We will use CSV files as our database.
- Reinforce and practice all of the Ruby and programming concepts we've covered in class
- Practice writing specs and using TDD
- Practice working with raw data and using it to create instances of a Ruby class
- Practice using Enumerable methods to work with collections of data or instances
- Practice organizing and working with multiple files in a single project.
Create a Ruby class to represent each kind of data in the support/ directory. In the Product Data section, there are detailed descriptions of each csv file contents and its relation to other objects in the system. Your implementation will have class methods to handle finding, sorting, and collecting the data into instances representing individual rows of data. Each of those instances will have instance methods to provide details about the object.
To manage our data classes we will use a file named /far_mar.rb. It should look something like:
# gems your project needs
require 'csv'
# our namespace module
module FarMar; end
# all of our data classes that live in the module
require 'lib/farmar_market'
# ...require all needed classesEach class you build will live in the /lib directory, and belong to the FarMar module:
# lib/farmar_market.rb
class FarMar::Market
# Your code goes here
endThe module provides a namespace for the application. A namespace ensures the classes we create will not 'collide' or 'overlap' with a class that could exist elsewhere in a codebase (like in a gem).
For example, Sale is a very generic class name that could very realistically exist in many codebases. Creating a module called FarMar allows us to specify which Sale we're talking about; FarMar::Sale is much more explicit and likely to be unique.
You must have 90% test coverage from simplecov. The HTML files that are generated from simplecov should not be included in your git repository. Tests should be in the form of minitest specs. Complete the necessary boilerplate to create a Rakefile and spec_helper.rb so that all of your tests run when you run $ rake from the project root.
Each individual market has many vendors associated with it. The FarMar::Market data, in order in the CSV, consists of:
- ID - (Fixnum) a unique identifier for that market
- Name - (String) the name of the market (not guaranteed unique)
- Address - (String) street address of the market
- City - (String) city in which the market is located
- County - (String) county in which the market is located
- State - (String) state in which the market is located
- Zip - (String) zipcode in which the market is located
Each vendor belongs to a market, the market_id field refers to the FarMar::Market ID field.
Each vendor has many products for sell. The FarMar::Vendor data, in order in the CSV, consists of:
- ID - (Fixnum) uniquely identifies the vendor
- Name - (String) the name of the vendor (not guaranteed unique)
- No. of Employees - (Fixnum) How many employees the vendor has at the market
- Market_id - (Fixnum) a reference to which market the vendor attends
Each product belongs to a vendor. The vendor_id field refers to the FarMar::Vendor ID field. The FarMar::Product data, in order in the CSV, consists of:
- ID - (Fixnum) uniquely identifies the product
- Name - (String) the name of the product (not guaranteed unique)
- Vendor_id - (Fixnum) a reference to which vendor sells this product
Each sale belongs to a vendor AND a product. The vendor_id and product_id fields refer to the FarMar::Vendor and FarMar::Product ID fields, respectively. The FarMar::Sale data, in order in the CSV, consists of:
- ID - (Fixnum) uniquely identifies the sale
- Amount - (Fixnum) the amount of the transaction, in cents (i.e., 150 would be $1.50)
- Purchase_time - (Datetime) when the sale was completed
- Vendor_id - (Fixnum) a reference to which vendor completed the sale
- Product_id - (Fixnum) a reference to which product was sold
- You'll be working as an individual on this project.
- Fork the Ada-C6 repo to your Github account.
- Clone your fork to your projects directory, and
cdinto the cloned repo. - Create a gemset for your project
$ echo 2.3.0 > .ruby-version$ echo farmar > .ruby-gemset$ cd .- Install necessary gems via Terminal:
$ gem install minitest-reporters$ gem install simplecov
- Create a class for each of the data types listed above. Each class should be a part of the
FarMarmodule. - You should be able to create instances of these classes that know about their associated data file.
- Create your
far_mar.rbfile which will bring together all classes created in the previous step. - Complete the boilerplate necessary for testing. You should be able to
$ rakefrom the project root to run your specs. Have at least one spec to verify this setup before submitting your baseline. - Once you have completed your baseline, you must submit a pull-request and get it approved by an instructor.
self.all: returns a collection of instances, representing all of the objects described in the CSVself.find(id): returns an instance of the object where the value of theidfield in the CSV matches the passed parameter.
#vendors: returns a collection ofFarMar::Vendorinstances that are associated with the market by themarket_idfield.
#market: returns theFarMar::Marketinstance that is associated with this vendor using theFarMar::Vendormarket_idfield#products: returns a collection ofFarMar::Productinstances that are associated by theFarMar::Productvendor_idfield.#sales: returns a collection ofFarMar::Saleinstances that are associated by thevendor_idfield.#revenue: returns the the sum of all of the vendor's sales (in cents)self.by_market(market_id): returns all of the vendors with the givenmarket_id
#vendor: returns theFarMar::Vendorinstance that is associated with this vendor using theFarMar::Productvendor_idfield#sales: returns a collection ofFarMar::Saleinstances that are associated using theFarMar::Saleproduct_idfield.#number_of_sales: returns the number of times this product has been sold.self.by_vendor(vendor_id): returns all of the products with the givenvendor_id
#vendor: returns theFarMar::Vendorinstance that is associated with this sale using theFarMar::Salevendor_idfield#product: returns theFarMar::Productinstance that is associated with this sale using theFarMar::Saleproduct_idfieldself.between(beginning_time, end_time): returns a collection of FarMar::Sale objects where the purchase time is between the two times given as arguments
#productsreturns a collection ofFarMar::Productinstances that are associated to the market through theFarMar::Vendorclass.self.search(search_term)returns a collection ofFarMar::Marketinstances where the market name or vendor name contain thesearch_term. For exampleFarMar::Market.search('school')would return 3 results, one being the market with id 75 (Fox School Farmers FarMar::Market).#prefered_vendor: returns the vendor with the highest revenue#prefered_vendor(date): returns the vendor with the highest revenue for the given date#worst_vendor: returns the vendor with the lowest revenue#worst_vendor(date): returns the vendor with the lowest revenue on the given date
self.most_revenue(n)returns the top n vendor instances ranked by total revenueself.most_items(n)returns the top n vendor instances ranked by total number of items soldself.revenue(date)returns the total revenue for that date across all vendors#revenue(date)returns the total revenue for that specific purchase date and vendor instance
self.most_revenue(n)returns the topnproduct instances ranked by total revenue
- Write additional rspec tests for any methods in the data classes that don't already have test coverage.
self.find_by_x(match): wherexis an attribute, returns a single instance whosexattribute (case-insensitive) equals thematchparameter. For instance,FarMar::Vendor.find_by_name("windler inc")could find aFarMar::Vendorwith name attribute "windler inc" or "Windler Inc".self.find_all_by_x(match): works just likefind_by_xbut returns a collection containing all possible matches. For exampleFarMar::Market.find_by_state("WA")could return all of theFarMar::Marketobjects with"WA"in their state field.
- Inheritance: Create a new class that defines the shared/duplicated methods (i.e.,
find,all). Update your data classes to inherit this class . - Composition with a Mixin: Create a new module that defines the duplicated methods (i.e.,
find,all). Update your data classes to mixin this module.