Created
September 14, 2013 01:00
-
-
Save steven-ferguson/6557860 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'pg' | |
require 'date' | |
require './lib/person' | |
require './lib/marriage' | |
require './lib/parent' | |
DB = PG.connect(:dbname => "family_tree") | |
def welcome | |
puts "\e[H\e[2J" | |
"Welcome to the family tree app!" | |
main_menu | |
end | |
def main_menu | |
puts "\nChoose one of the following: " | |
puts "1. Add a family member" | |
puts "2. View all people" | |
puts "3. Update information about a person" | |
puts "4. List relatives of a person" | |
input = gets.to_i | |
case input | |
when 1 | |
add_person | |
main_menu | |
when 2 | |
display_people | |
when 3 | |
person = select_person | |
update_menu(person) | |
when 4 | |
person = select_person | |
list_relatives_menu(person) | |
else | |
main_menu | |
end | |
end | |
def update_menu(person) | |
puts "\nChoose one of the following: " | |
puts "1. Add a spouse" | |
puts "2. Add a child" | |
puts "0. Return to main menu" | |
user_choice = gets.to_i | |
case user_choice | |
when 1 | |
add_spouse(person) | |
when 2 | |
add_child(person) | |
else | |
main_menu | |
end | |
end | |
def select_person | |
display_people | |
puts "Select the person:" | |
people = Person.all | |
person = people[gets.to_i - 1] | |
puts "\n\n #{person.first_name} #{person.last_name} selected" | |
person | |
end | |
def add_person | |
puts "First name?" | |
first_name = gets.chomp | |
puts "Last name?" | |
last_name = gets.chomp | |
puts "Birthdate? Format YYYY-MM-DD" | |
birthday = gets.chomp | |
person = Person.new({ 'first_name' => first_name, 'last_name' => last_name, 'birth_date' => birthday} ) | |
person.save | |
puts "#{first_name} #{last_name} added!" | |
person | |
end | |
def add_spouse(person) | |
if person.married? | |
puts "#{person.first_name} #{person.last_name} is already married to #{person.get_spouse.first_name} #{person.get_spouse.last_name}." | |
else | |
puts "\nEnter spouse's information:" | |
spouse = add_person | |
puts "\nWedding date? Format YYYY-MM-DD" | |
wedding_date = gets.chomp | |
marriage = Marriage.new({'people_id_1' => person.id, 'people_id_2' => spouse.id, 'wedding_date' => wedding_date}) | |
marriage.save | |
puts "Marriage saved!" | |
end | |
update_menu(person) | |
end | |
def add_child(person) | |
puts "\nEnter child information:" | |
child = add_person | |
person.add_child(child) | |
puts "#{child.first_name} #{child.last_name} is now a chld of #{person.first_name} #{person.last_name}" | |
main_menu | |
end | |
def display_people | |
puts "\n\n" | |
Person.all.each_with_index do |person, index| | |
puts "#{index + 1}. #{person.first_name} #{person.last_name}, Birthday: #{person.birth_date}" | |
end | |
puts "\n\n" | |
end | |
def list_relatives_menu(person) | |
puts "\nChoose one of the following options: " | |
puts "1. List spouse" | |
puts "2. List children" | |
puts "3. List parents" | |
puts "4. List siblings" | |
puts "0. Return to main menu" | |
user_choice = gets.to_i | |
case user_choice | |
when 1 | |
if person.married? | |
puts "#{person.first_name} #{person.last_name} is married to #{person.get_spouse.first_name} #{person.get_spouse.last_name}." | |
else | |
puts "#{person.first_name} #{person.last_name} is not married." | |
end | |
when 2 | |
if person.has_children? | |
puts "\nChildren:" | |
person.get_children.each_with_index do |child, index| | |
puts "#{index + 1}. #{child.first_name} #{child.last_name}, Birthday: #{child.birth_date}" | |
end | |
else | |
puts "#{person.first_name} #{person.last_name} does not have any children." | |
end | |
when 3 | |
if person.has_parents? | |
puts "\nParents:" | |
person.get_parents.each_with_index do |parent, index| | |
puts "#{index + 1}. #{parent.first_name} #{parent.last_name}, Birthday: #{parent.birth_date}" | |
end | |
else | |
puts "#{person.first_name} #{person.last_name} does not have any parents." | |
end | |
when 4 | |
if person.has_siblings? | |
puts "\nSiblings:" | |
person.get_siblings.each_with_index do |sibling, index| | |
puts "#{index + 1}. #{sibling.first_name} #{sibling.last_name}, Birthday: #{sibling.birth_date}" | |
end | |
else | |
puts "#{person.first_name} #{person.last_name} does not have any siblings." | |
end | |
else | |
main_menu | |
end | |
list_relatives_menu(person) | |
end | |
welcome |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Marriage | |
attr_reader :person_1_id, :person_2_id, :wedding_date, :id | |
def initialize(attributes) | |
@person_1_id = attributes['people_id_1'].to_i | |
@person_2_id = attributes['people_id_2'].to_i | |
@wedding_date = Date.parse(attributes['wedding_date']) | |
@id = attributes['id'].to_i | |
end | |
def save | |
result = DB.exec("INSERT INTO marriages (people_id_1, people_id_2, wedding_date) VALUES (#{@person_1_id}, #{@person_2_id}, '#{@wedding_date.to_s}') RETURNING id;") | |
@id = result.first['id'].to_i | |
end | |
def self.all | |
DB.exec("SELECT * FROM marriages").inject([]) do |marriages, result| | |
marriages << Marriage.new(result) | |
end | |
end | |
def ==(another_marriage) | |
@person_1_id == another_marriage.person_1_id && @person_2_id == another_marriage.person_2_id && @wedding_date == another_marriage.wedding_date | |
end | |
def get_spouses | |
[Person.find(@person_1_id), Person.find(@person_2_id)] | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe Marriage do | |
let(:barack) { | |
person = Person.new({ 'first_name' => 'Barack', 'last_name' => 'Obama', 'birth_date' => '1964-09-14' }) | |
person.save | |
person | |
} | |
let(:michelle) { | |
person = Person.new({ 'first_name' => 'Michelle', 'last_name' => 'Obama', 'birth_date' => '1967-03-28'}) | |
person.save | |
person | |
} | |
let(:new_marriage) { | |
{'people_id_1' => barack.id, 'people_id_2' => michelle.id, 'wedding_date' => '1998-05-21'} | |
} | |
it 'is initialized with a hash of attributes' do | |
marriage = Marriage.new(new_marriage) | |
marriage.should be_an_instance_of Marriage | |
end | |
it 'tells you the id of person 1' do | |
marriage = Marriage.new(new_marriage) | |
marriage.person_1_id.should eq barack.id | |
end | |
it 'tells you the id of person 2' do | |
marriage = Marriage.new(new_marriage) | |
marriage.person_2_id.should eq michelle.id | |
end | |
it 'tells you the marriage date' do | |
marriage = Marriage.new(new_marriage) | |
marriage.wedding_date.to_s.should eq '1998-05-21' | |
end | |
it 'allows you to save a marriage to the database' do | |
marriage = Marriage.new(new_marriage) | |
marriage.save | |
Marriage.all.should eq [marriage] | |
end | |
it 'sets the marriage id when saved' do | |
marriage = Marriage.new(new_marriage) | |
marriage.save | |
Marriage.all.first.id.should eq marriage.id | |
end | |
it 'gets the spouses in the marriage' do | |
marriage = Marriage.new(new_marriage) | |
marriage.get_spouses.include?(barack).should eq true | |
marriage.get_spouses.include?(michelle).should eq true | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# class Parent | |
# def initialize(attributes) | |
# @parent_id = attributes['parent_id'].to_i | |
# @child_id = attributes['child_id'].to_i | |
# end | |
# end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# require 'spec_helper' | |
# describe 'Parent' do | |
# let(:barack) { | |
# person = Person.new({ 'first_name' => 'Barack', 'last_name' => 'Obama', 'birth_date' => '1964-09-14' }) | |
# person.save | |
# person | |
# } | |
# let(:malia) { | |
# person = Person.new({ 'first_name' => 'Malia', 'last_name' => 'Obama', 'birth_date' => '2000-11-05' }) | |
# person.save | |
# person | |
# } | |
# it 'is initialized with a hash of attributes' do | |
# parent = Parent.new({'parent_id' => barack.id, 'child_id' => malia.id}) | |
# parent.should be_an_instance_of Parent | |
# end | |
# it 'lets you return its parent id number' do | |
# parent = Parent.new({'parent_id' => barack.id, 'child_id' => malia.id}) | |
# parent.parent_id.should eq barack.id | |
# end | |
# end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Person | |
attr_reader :first_name, :last_name, :birth_date, :id | |
def initialize(attributes) | |
@first_name = attributes['first_name'].capitalize | |
@last_name = attributes['last_name'].capitalize | |
@birth_date = Date.parse(attributes['birth_date']) | |
@id = attributes['id'].to_i | |
end | |
def save | |
result = DB.exec("INSERT INTO people (first_name, last_name, birth_date) VALUES('#{@first_name}', '#{@last_name}', '#{@birth_date.to_s}') RETURNING id;") | |
@id = result.first['id'].to_i | |
end | |
def self.all | |
DB.exec("SELECT * FROM people;").inject([]) do |people, result| | |
people << Person.new(result) | |
end | |
end | |
def ==(another_person) | |
@first_name == another_person.first_name && @last_name == another_person.last_name && @birth_date == another_person.birth_date | |
end | |
def self.find(person_id) | |
results = DB.exec("SELECT * FROM people WHERE id = #{person_id};") | |
Person.new(results.first) | |
end | |
def married? | |
!DB.exec("SELECT * FROM marriages WHERE people_id_1 = #{@id} OR people_id_2 = #{@id};").first.nil? | |
end | |
def get_spouse | |
marriage = Marriage.new(DB.exec("SELECT * FROM marriages WHERE people_id_1 = #{@id} OR people_id_2 = #{@id};").first) | |
marriage.get_spouses.find {|person| @id != person.id } | |
end | |
def add_child(child) | |
DB.exec("INSERT INTO parents_children (parent_id, child_id) VALUES (#{@id}, #{child.id});") | |
end | |
def get_children | |
results = DB.exec("SELECT * FROM parents_children WHERE parent_id = #{@id};") | |
results.inject([]) do |children, result| | |
children << Person.find(result['child_id'].to_i) | |
end | |
end | |
def get_parents | |
results = DB.exec("SELECT * FROM parents_children WHERE child_id = #{@id};") | |
results.inject([]) do |parents, result| | |
parents << Person.find(result['parent_id'].to_i) | |
end | |
end | |
def get_siblings | |
get_parents.inject([]) do |siblings, parent| | |
siblings + parent.get_children.select { |child| child != self && !siblings.include?(child)} | |
end | |
end | |
def has_parents? | |
get_parents != [] | |
end | |
def has_children? | |
get_children != [] | |
end | |
def has_siblings? | |
get_siblings != [] | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe Person do | |
let(:barack) { { 'first_name' => 'Barack', 'last_name' => 'Obama', 'birth_date' => '1964-09-14' } } | |
let(:michelle) { { 'first_name' => 'Michelle', 'last_name' => 'Obama', 'birth_date' => '1967-03-28'} } | |
let(:malia) { | |
person = Person.new({ 'first_name' => 'Malia', 'last_name' => 'Obama', 'birth_date' => '2000-11-05' }) | |
person.save | |
person | |
} | |
let(:sasha) { | |
person = Person.new({ 'first_name' => 'Sasha', 'last_name' => 'Obama', 'birth_date' => '2002-09-11' }) | |
person.save | |
person | |
} | |
it 'is initialized with a hash of attributes' do | |
person = Person.new(barack) | |
person.should be_an_instance_of Person | |
end | |
it 'tells you the person\'s first name' do | |
person = Person.new(barack) | |
person.first_name.should eq 'Barack' | |
end | |
it "tells you the person's last name" do | |
person = Person.new(barack) | |
person.last_name.should eq "Obama" | |
end | |
it "tells you the person's birth date" do | |
person = Person.new(barack) | |
person.birth_date.to_s.should eq "1964-09-14" | |
end | |
it "tells you the person's id" do | |
person = Person.new(barack) | |
person.save | |
person.id.should be_an_instance_of Fixnum | |
end | |
it "lets you save it to the database" do | |
person = Person.new(barack) | |
person.save | |
Person.all.should eq [person] | |
end | |
it 'sets its id when saved' do | |
person = Person.new(barack) | |
person.save | |
Person.all.first.id.should eq person.id | |
end | |
it "describes two people as equal if all of their attributes are equal" do | |
person = Person.new(barack) | |
person2 = Person.new(barack) | |
person.should eq person2 | |
end | |
it "finds a person in the database" do | |
person = Person.new(barack) | |
person.save | |
Person.find(person.id).should eq person | |
end | |
it 'tells you a person\'s spouse' do | |
person = Person.new(barack) | |
person.save | |
person2 = Person.new(michelle) | |
person2.save | |
marriage = Marriage.new({'people_id_1' => person.id, 'people_id_2' => person2.id, 'wedding_date' => '1998-05-21'}) | |
marriage.save | |
person.get_spouse.should eq person2 | |
end | |
it 'gets the spouse when the person is listed as the second person in the marriage' do | |
person = Person.new(barack) | |
person.save | |
person2 = Person.new(michelle) | |
person2.save | |
marriage = Marriage.new({'people_id_1' => person.id, 'people_id_2' => person2.id, 'wedding_date' => '1998-05-21'}) | |
marriage.save | |
person2.get_spouse.should eq person | |
end | |
it 'tells you if the person is married or not' do | |
person = Person.new(barack) | |
person.save | |
person.married?.should eq false | |
end | |
it 'tells you if a person has a spouse in the databse' do | |
person = Person.new(barack) | |
person.save | |
person2 = Person.new(michelle) | |
person2.save | |
marriage = Marriage.new({'people_id_1' => person.id, 'people_id_2' => person2.id, 'wedding_date' => '1998-05-21'}) | |
marriage.save | |
person.married?.should eq true | |
end | |
it 'lets you add a child' do | |
person = Person.new(barack) | |
person.save | |
person.add_child(malia) | |
# DB.should_receive(:exec).with("whatever SQL gets executed by person.add_child") | |
result = DB.exec("SELECT * FROM parents_children WHERE child_id = #{malia.id};") | |
result.first['parent_id'].to_i.should eq person.id | |
end | |
it 'lets you get all children of person' do | |
person = Person.new(barack) | |
person.save | |
person.add_child(malia) | |
person.add_child(sasha) | |
person.get_children.include?(malia).should eq true | |
person.get_children.include?(sasha).should eq true | |
end | |
it 'lets you get the parents of a person' do | |
parent1 = Person.new(barack) | |
parent2 = Person.new(michelle) | |
parent1.save | |
parent2.save | |
parent1.add_child(malia) | |
parent2.add_child(malia) | |
malia.get_parents.include?(parent1).should eq true | |
malia.get_parents.include?(parent2).should eq true | |
end | |
it 'tells you if a person has parents in the database' do | |
parent1 = Person.new(barack) | |
parent2 = Person.new(michelle) | |
parent1.save | |
parent2.save | |
parent1.add_child(malia) | |
parent2.add_child(malia) | |
malia.has_parents?.should eq true | |
end | |
it 'tells you if a person has parents in the database' do | |
malia.has_parents?.should eq false | |
end | |
it 'tells you if a person has children in the database' do | |
parent = Person.new(barack) | |
parent.save | |
parent.add_child(sasha) | |
parent.has_children?.should eq true | |
end | |
it 'tells you if a person has children in the database' do | |
parent = Person.new(barack) | |
parent.save | |
parent.has_children?.should eq false | |
end | |
it 'gets the siblings of a person' do | |
person = Person.new(barack) | |
person.save | |
person.add_child(malia) | |
person.add_child(sasha) | |
malia.get_siblings.should eq [sasha] | |
end | |
it 'gets the siblings of a person with more than one parent in the database' do | |
person = Person.new(barack) | |
person.save | |
person2 = Person.new(michelle) | |
person2.save | |
person.add_child(malia) | |
person.add_child(sasha) | |
person2.add_child(malia) | |
person2.add_child(sasha) | |
malia.get_siblings.should eq [sasha] | |
end | |
it 'tells you if a person has siblings' do | |
person = Person.new(barack) | |
person.save | |
person.add_child(malia) | |
person.add_child(sasha) | |
malia.has_siblings?.should eq true | |
end | |
it 'tells you if a person has siblings' do | |
malia.has_siblings?.should eq false | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require 'pg' | |
require 'date' | |
require 'person' | |
require 'marriage' | |
DB = PG.connect(:dbname => "family_tree_test") | |
RSpec.configure do |config| | |
config.after(:each) do | |
DB.exec("DELETE FROM people *;") | |
DB.exec("DELETE FROM marriages *;") | |
DB.exec("DELETE FROM parents_children *;") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment