We have updated the content of our program. To access the current Software Engineering curriculum visit curriculum.turing.edu.
Black Thursday Iteration 0 - Merchants & Items
The goal of this iteration is to get the ball rolling by focusing on a “Data Access Layer” for multiple CSV files.
Data Access Layer
The idea of a DAL is to write classes which load and parse your raw data, allowing your system to then interact with rich Ruby objects to do more complex analysis. In this iteration, we’ll build the beginnings of a DAL by building the classes described below:
Merchant
The Merchant is one of the critical concepts in our data hierarchy.
id
- returns the integerid
of the merchantname
- returns the name of the merchant
We create an instance like this:
m = Merchant.new({:id => 5, :name => "Turing School"})
# => <Merchant...>
MerchantRepository
The MerchantRepository
is responsible for holding and searching our Merchant
instances. It offers the following methods:
all
- returns an array of all knownMerchant
instancesfind_by_id(id)
- returns eithernil
or an instance ofMerchant
with a matching IDfind_by_name(name)
- returns eithernil
or an instance ofMerchant
having done a case insensitive searchfind_all_by_name(name)
- returns either[]
or one or more matches which contain the supplied name fragment, case insensitivecreate(attributes)
- create a newMerchant
instance with the providedattributes
. The newMerchant
’s id should be the current highestMerchant
id plus 1.update(id, attributes)
- update theMerchant
instance with the correspondingid
with the providedattributes
. Only the merchant’sname
attribute can be updated.delete(id)
- delete theMerchant
instance with the correspondingid
The data can be found in data/merchants.csv
. The instance should be created in the SalesEngine
(see below), so that the instance is created and used like this:
se = SalesEngine.from_csv({
:items => "./data/items.csv",
:merchants => "./data/merchants.csv",
})
mr = se.merchants
merchant = mr.find_by_name("CJsDecor")
# => <Merchant...>
Item
The Item instance offers the following methods:
id
- returns the integer id of the itemname
- returns the name of the itemdescription
- returns the description of the itemunit_price
- returns the price of the item formatted as aBigDecimal
created_at
- returns aTime
instance for the date the item was first createdupdated_at
- returns aTime
instance for the date the item was last modifiedmerchant_id
- returns the integer merchant id of the item
It also offers the following method:
unit_price_to_dollars
- returns the price of the item in dollars formatted as aFloat
We create an instance like this:
i = Item.new({
:id => 1,
:name => "Pencil",
:description => "You can use it to write things",
:unit_price => BigDecimal(10.99,4),
:created_at => Time.now,
:updated_at => Time.now,
:merchant_id => 2
})
# => <Item...>
i.unit_price_to_dollars
# => 10.99
ItemRepository
The ItemRepository
is responsible for holding and searching our Item
instances. This object represents one line of data from the file items.csv
.
It offers the following methods:
all
- returns an array of all knownItem
instancesfind_by_id(id)
- returns eithernil
or an instance ofItem
with a matching IDfind_by_name(name)
- returns eithernil
or an instance ofItem
having done a case insensitive searchfind_all_with_description(description)
- returns either[]
or instances ofItem
where the supplied string appears in the item description (case insensitive)find_all_by_price(price)
- returns either[]
or instances ofItem
where the supplied price exactly matchesfind_all_by_price_in_range(range)
- returns either[]
or instances ofItem
where the supplied price is in the supplied range (a single Rubyrange
instance is passed in)find_all_by_merchant_id(merchant_id)
- returns either[]
or instances ofItem
where the supplied merchant ID matches that suppliedcreate(attributes)
- create a newItem
instance with the providedattributes
. The newItem
’s id should be the current highestItem
id plus 1.update(id, attributes)
- update theItem
instance with the correspondingid
with the providedattributes
. Only the item’sname
,description
, andunit_price
attributes can be updated. This method will also change the itemsupdated_at
attribute to the current time.delete(id)
- delete theItem
instance with the correspondingid
Similar to the MerchantRepository
, the ItemRepository
is initialized from the SalesEngine
class (see below), and its data can be found in data/items.csv
. It is initialized and used like this:
se = SalesEngine.from_csv({
:items => "./data/items.csv",
:merchants => "./data/merchants.csv"
})
ir = se.items
item = ir.find_by_name("Item Repellat Dolorum")
# => <Item...>
SalesEngine
Once we have an ItemRepository
and a MerchantRepository
, we can tie everything together with one common root, a SalesEngine
instance:
se = SalesEngine.from_csv({
:items => "./data/items.csv",
:merchants => "./data/merchants.csv",
})
From there we can find the child instances:
items
returns an instance ofItemRepository
with all the item instances loadedmerchants
returns an instance ofMerchantRepository
with all the merchant instances loaded