Skip to content

Instantly share code, notes, and snippets.

@steven-ferguson
Created September 14, 2013 01:00
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 steven-ferguson/6557860 to your computer and use it in GitHub Desktop.
Save steven-ferguson/6557860 to your computer and use it in GitHub Desktop.
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
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
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
# class Parent
# def initialize(attributes)
# @parent_id = attributes['parent_id'].to_i
# @child_id = attributes['child_id'].to_i
# end
# end
# 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
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
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
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