Skip to content

Instantly share code, notes, and snippets.

@oobbles
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oobbles/78f6cbdcce0b2e8d8c94 to your computer and use it in GitHub Desktop.
Save oobbles/78f6cbdcce0b2e8d8c94 to your computer and use it in GitHub Desktop.
Heavy Truck Parts Database
class Category
attr_reader :id
attr_accessor :category
# Initializes a new category object
#
# id (optional) - Integer of the zipcode record in categories table
def initialize(id=nil, category=nil)
@id = id
@category = category
end
# Get all category records from the category table
#
# Returns an Array of Category Objects
def self.all
results = CONNECTION.execute('SELECT * FROM categories;')
results_as_objects = []
results.each do |result_hash|
results_as_objects << ZipCode.new(result_hash["id"], result_hash=["category"])
end
return results_as_objects
end
# Find a category based on its ID.
#
# id - The Integer ID of the category to return.
#
# Returns a Category object.
def self.find(id)
@id = id
result = CONNECTION.execute("SELECT * FROM categories WHERE id = #{@id};").first
temp_category = result["category"]
Category.new(id, temp_category)
end
# Utility method gets category id and if none exists, returns false
#
# category - The String that is used to search for its corresponding id
#
# Returns the category id number as an Integer
def self.get_id(category)
cat_id = CONNECTION.execute("SELECT id FROM categories WHERE category = '#{category}'")
if cat_id.count == 0
return false
else
return cat_id.first['id'].to_i
end
end
# Utility methods to add, update and delete. Note the delete prevents
# erasing a record if its id is being used in the truck_parts table.
def self.add(category)
CONNECTION.execute("INSERT INTO categories (category) VALUES ('#{category}';")
end
def change_name(new_category)
CONNECTION.execute("UPDATE categories SET name = '#{new_category}' WHERE id = #{@id};")
end
def delete
category = CONNECTION.execute("SELECT COUNT(*) FROM truck_parts WHERE category_id = #{id};")
if category == 0
CONNECTION.execute("DELETE FROM categories WHERE id = #{@id};")
else
false
end
end
# Method called on an instance of the Category class returns any parts from
# the truck_part table associated with the @id as an array.
def truck_parts
parts = []
results = CONNECTION.execute("SELECT part_name FROM truck_parts WHERE category_id = #{@id};")
results.each do |hash|
parts << hash["part_name"]
end
return parts
end
end
require "sqlite3"
require 'active_support/all'
# Load/create our database for this program.
CONNECTION = SQLite3::Database.new("heavytruckparts.db")
# Make the tables.
CONNECTION.execute("CREATE TABLE IF NOT EXISTS categories (id INTEGER PRIMARY KEY, category TEXT);")
CONNECTION.execute("CREATE TABLE IF NOT EXISTS zip_codes (id INTEGER PRIMARY KEY, zip_code INTEGER);")
CONNECTION.execute("CREATE TABLE IF NOT EXISTS truck_parts (id INTEGER PRIMARY KEY, part_name TEXT, category_id INTEGER, zip_code_id INTEGER, quantity, INTEGER);")
# Get results as an Array of Hashes.
CONNECTION.results_as_hash = true
# ---------------------------------------------------------------------
require_relative "truckpart.rb"
require_relative "category.rb"
require_relative "zipcode.rb"
puts "
╦ ╦┌─┐┌─┐┬ ┬┬ ┬╔╦╗┬─┐┬ ┬┌─┐┬┌─╔═╗┌─┐┬─┐┌┬┐┌─┐
╠═╣├┤ ├─┤└┐┌┘└┬┘ ║ ├┬┘│ ││ ├┴┐╠═╝├─┤├┬┘ │ └─┐
╩ ╩└─┘┴ ┴ └┘ ┴ ╩ ┴└─└─┘└─┘┴ ┴╩ ┴ ┴┴└─ ┴ └─┘
"
puts "Welcome to the HeavyTruckParts Manager"
puts "Please make your selection. Options are as follows: "
puts "(L)ist all parts in the database"
puts "(A)dd a part"
puts "(S)earch for parts by category or search for parts by (Z)ip code."
puts "You may also (E)xit "
answer = gets.chomp.titleize
while answer != "E" do
if answer == "L"
TruckPart.all.each do |part|
puts "#{part.part_name}".ljust(23) + "#{part.category}".ljust(18) +"#{part.zip_code}"
end
elsif answer == "A"
puts "Enter the part name: "
part_name = gets.chomp.downcase.titleize
puts "Enter the category (New, Used, Reconditioned)"
category = gets.chomp.downcase.titleize
puts "Enter the zip code: "
zip_code = gets.chomp.to_i
puts "Quantity? Defaults to 1"
quantity = gets.chomp.to_i
if TruckPart.add(part_name, category, zip_code, quantity)
puts "Your part was successfully saved."
else
puts "There was an error adding your part."
end
elsif answer == "S"
puts "Do you want to see parts that are (1)new, (2)used or (3)reconditioned?"
answer =Category.new(gets.chomp.to_i)
puts answer.truck_parts
elsif answer == "Z"
puts "Enter 5 digit zip code to see parts in that area: "
answer_to_id = ZipCode.get_id(gets.chomp)
answer =ZipCode.new(answer_to_id)
puts answer.truck_parts
else
break
end
puts ""
puts "Please make your selection. Options are as follows: "
puts "(L)ist all parts in the database"
puts "(A)dd a part"
puts "(S)earch for parts by category or search for parts by (Z)ip code."
puts "You may also (E)xit "
answer = gets.chomp.titleize
end
class TruckPart
attr_accessor :id, :part_name, :category_id, :zip_code_id, :quantity
# Initializes a new truck_part object.
#
# id (optional) - Integer of the part_name record in truck_parts table.
#
# part_name (optional) - String of the part name.
#
# category_id (optional) - Integer representing category name in Category
# table.
# zip_code_id (optional) - Integer representing zip code in Zipcode table.
#
# quantity (optional) - Integer of total specific parts in specific
# location.
def initialize(id=nil, part_name=nil, category_id=nil, zip_code_id=nil, quantity=nil)
@id = id
@part_name = part_name
@category_id = category_id
@zip_code_id = zip_code_id
@quantity = quantity
end
# Get all part records from the database.
#
# Returns an Array containing TruckPart objects.
def self.all
results = CONNECTION.execute('SELECT * FROM truck_parts;')
results_as_objects = []
results.each do |result_hash|
results_as_objects << TruckPart.new(result_hash["id"], result_hash["part_name"],
result_hash["category_id"], result_hash["zip_code_id"], result_hash["quantity"])
end
return results_as_objects
end
# Find a truck_part based on its ID.
#
# id - The Integer ID of the truck_part to return.
#
# Returns a TruckPart object.
def self.find(id)
@id = id
result = CONNECTION.execute("SELECT * FROM truck_parts WHERE id = #{@id};").first
temp_part_name = result["part_name"]
temp_category_id = result["category_id"]
temp_zip_code_id = result["zip_code_id"]
temp_quantity = result["quantity"]
TruckPart.new(id, temp_part_name, temp_category_id, temp_zip_code_id, temp_quantity)
end
# Method adds a row to the truck_parts database
#
# part_name - The String that is put in the part_name column
# category - The String that is converted to its coresponding id using
# Category.get_id(category) Must be New, Used or Reconditioned
#
# zip_code - The Integer that is converted to its id via ZipCode.get_id
#
# Returns TruckPart object
def self.add(part_name, category, zip_code, quantity=1)
temp_truck_part = TruckPart.new(nil, part_name, nil, nil, quantity=1)
return false if zip_code.to_i == 0
zip_id = ZipCode.get_id(zip_code)
temp_truck_part.zip_code_id = zip_id
cat_id = Category.get_id(category)
return false unless cat_id
temp_truck_part.category_id = cat_id
sql = "SELECT * FROM truck_parts WHERE part_name = '#{part_name}' AND
zip_code_id = #{zip_id} AND category_id = #{cat_id};"
existing_part = CONNECTION.execute(sql)
if existing_part.count > 0
existing_part_hash = existing_part.first
temp_truck_part.quantity = existing_part_hash["quantity"]
temp_truck_part.id = existing_part_hash["id"]
temp_truck_part.increment_quantity(quantity)
temp_truck_part.save
else
sql = "INSERT INTO truck_parts (part_name, category_id, zip_code_id,
quantity) VALUES ('#{part_name}', #{cat_id}, #{zip_id}, #{quantity});"
CONNECTION.execute(sql)
temp_truck_part.id = CONNECTION.last_insert_row_id
end
return temp_truck_part
end
def increment_quantity(quantity_argument)
@quantity += quantity_argument
end
# Method deletes row in truck_parts table corresponding to the id of the
# TruckParts instance it is called on.
#
# Returns nil.
def delete
CONNECTION.execute("DELETE FROM truck_parts WHERE id = #{@id};")
end
def category
Category.find(@category_id).category
end
def zip_code
ZipCode.find(@zip_code_id).zip_code
end
# Returns an empty Array.
def save
CONNECTION.execute("UPDATE truck_parts SET part_name = '#{@part_name}',
category_id = #{@category_id}, zip_code_id = #{@zip_code_id}, quantity = #{@quantity} WHERE id = #{@id};")
end
end
class ZipCode
attr_reader :id
attr_accessor :zip_code
# Initializes a new zipcode object
#
# id (optional) - Integer of the zipcode record in zip_codes table
#
# zip_code (optional) - Integer of the zip_code in the zip_codes table
def initialize(id=nil, zip_code=nil)
@id = id
@zip_code = zip_code
end
# Get all zip code records from the ZipCode table
#
# Returns an Array of ZipCode Objects
def self.all
results = CONNECTION.execute('SELECT * FROM zip_codes;')
results_as_objects = []
results.each do |result_hash|
results_as_objects << ZipCode.new(result_hash["id"], result_hash=["zip_code"])
end
return results_as_objects
end
# Find a zip code based on its ID.
#
# id - The Integer ID of the zipcode to return.
#
# Returns a ZipCode object.
def self.find(id)
@id = id
result = CONNECTION.execute("SELECT * FROM zip_codes WHERE id = #{@id};").first
temp_zip_code = result["zip_code"]
ZipCode.new(id, temp_zip_code)
end
# Class utility method gets zip code id and if none exists, enters the zip
# code argument in to the zip code table.
#
# zip - The Integer that is used to search for its corresponding id
#
# Returns the zip code id number as an Integer
def self.get_id(zip)
zip_id = CONNECTION.execute("SELECT id FROM zip_codes WHERE zip_code = #{zip};")
if zip_id.count == 0
add(zip)
else
zip_id.first['id'].to_i
end
end
# Utility method to add a zip code, returns an empty Array.
def self.add(zip_code)
CONNECTION.execute("INSERT INTO zip_codes (zip_code) VALUES (#{zip_code});")
return CONNECTION.last_insert_row_id
end
# Utility method to change a current zip code to new zip code. Returns an
# empty Array.
def change_name(new_zip_code)
CONNECTION.execute("UPDATE zip_codes SET zip_code = '#{new_zip_code}' WHERE id = #{@id};")
end
# Utility method to delete a current zip code. Does not allow a zipcode to be
# deleted if its ID is used in the truck_parts table. Returns a Boolean.
def delete
zip_codes_in_table = CONNECTION.execute("SELECT COUNT(*) FROM truck_parts WHERE zip_code_id = #{id};")
if zip_codes_in_table == 0
CONNECTION.execute("DELETE FROM zip_codes WHERE id = #{@id};")
else
false
end
end
# Method called on an instance of the ZipCode class, passed 5 digit Integer
# and returns the corresponding id from the zip_code table
def get_id(zipcode)
zipcode = @id
end
# Method called on an instance of the ZipCode class returns any parts from
# the truck_part table associated with the @id as an array.
def truck_parts
parts = []
results = CONNECTION.execute("SELECT part_name FROM truck_parts WHERE zip_code_id = #{@id};")
results.each do |hash|
parts << hash["part_name"]
end
return parts
end
end
@sumeetjain
Copy link

https://gist.github.com/oobbles/78f6cbdcce0b2e8d8c94#file-truckpart-rb-L19-L37 - Indentation

I like that you've been thoughtful about the documentation, but I'd like to see documentation for each method. Otherwise changing the order that methods are written (which you or a future developer on your team could do) will invalidate documentation. Also part of my intention for you documenting each method is forcing you to be deliberate about knowing what a method actually returns.

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