Skip to content

Commit

Permalink
further refactoring of Checkin model
Browse files Browse the repository at this point in the history
  • Loading branch information
lazylester committed Oct 27, 2012
1 parent 28efbae commit ac76cbf
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 39 deletions.
52 changes: 37 additions & 15 deletions app/domain_models/checkin.rb
Original file line number Diff line number Diff line change
@@ -1,41 +1,63 @@
class Checkin
class InvalidClientError < StandardError; end
class InvalidHouseholdCheckinError < StandardError; end
attr_reader :id
attr_accessor :client, :household_checkin
attr_accessor :client, :household_checkin, :household, :client_checkins

def self.create(client)
new(:client => client).save
end

def initialize(attrs)
@client = attrs[:client]
@household_checkin = attrs[:household_checkin]
if @client
raise InvalidClientError if !@client.is_a?(Client)
@household = @client.household
raise InvalidClientError if !@household
end
@household_checkin = attrs[:household_checkin] || HouseholdCheckin.new(:household_id => household.id)
raise InvalidHouseholdCheckinError if !@household_checkin.is_a?(HouseholdCheckin)
if household_checkin = attrs[:household_checkin]
@household = Household.find(household_checkin.household_id)
end
@client_checkins = attrs[:client_checkins].blank? ?
@household.clients.collect { |c| ClientCheckin.new(:client_id => c.id, :household_checkin => household_checkin) } :
attrs[:client_checkins]
end

def save
@id = HouseholdCheckin.create_for(client)
household_checkin.save
client_checkins.each do |cc|
cc.household_checkin_id = household_checkin.id
if cc.client_id == client.id
cc.primary = true
end
cc.save
@id = cc.id
end
self
end

def update_for(client_id, client_checkin_id, docs)
grouped_by_association_docs = docs.group_by{|doc| doc['doctype'] == 'id' ? 'client' : 'household' }
client_docs = grouped_by_association_docs['client']
household_docs = grouped_by_association_docs['household']

household_checkin_attributes = household_docs.inject({}) do |hash, doc|
hash[doc['doctype'] + '_warn'] = doc['warned']
hash['household_id'] ||= doc['association_id']
hash
end
client_docs = docs.select{|doc| doc['doctype'] == 'id'}
household_docs = docs.select{|doc| doc['doctype'] != 'id'}

household_checkin.update_attributes(household_checkin_attributes)
household_checkin_attributes = HouseholdCheckin.extract_attributes_from_docs(household_docs)

ClientCheckin.update_collection(client_id, client_checkin_id, client_docs, household_checkin.id)
household_checkin.update_attributes(household_checkin_attributes)

client_checkins.each do |checkin|
doc = client_docs.detect{|doc| doc[:association_id].to_i == checkin.client_id}
checkin.update_attributes(:id_warn => (doc['warned'] == "true") || doc['warned'] == '1')
end
end

def self.find_by_client_checkin_id(client_checkin_id)
client_checkin = ClientCheckin.find(client_checkin_id)
new(:household_checkin => HouseholdCheckin.find(client_checkin.household_checkin_id))
client = Client.find(client_checkin.client_id)
household_checkin = HouseholdCheckin.find(client_checkin.household_checkin_id)
client_checkins = ClientCheckin.where('household_checkin_id = ?',household_checkin.id)
new(:household_checkin => household_checkin, :client_checkins => client_checkins, :client => client)
end

end
18 changes: 0 additions & 18 deletions app/models/client_checkin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,6 @@ class ClientCheckin < ActiveRecord::Base
belongs_to :client
belongs_to :household_checkin

def self.create_collection(primary_client, clients, household_checkin)
clients.each do |client|
primary = client == primary_client
checkin = create(:client_id => client.id, :household_checkin_id => household_checkin.id, :primary => primary, :id_warn => false)
@primary_checkin_id = checkin.id if primary
end
@primary_checkin_id
end

def self.update_collection(client_id, client_checkin_id, docs, household_checkin_id)
collection = where('household_checkin_id = ?', household_checkin_id)
collection.each do |checkin|
doc = docs.detect{|doc| doc[:association_id].to_i == checkin.client_id}
checkin.update_attributes(:id_warn => (doc['warned'] == "true") || doc['warned'] == '1')
end
client_checkin_id
end

def related_client_checkins
household_checkin.client_checkins
end
Expand Down
11 changes: 5 additions & 6 deletions app/models/household_checkin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ class HouseholdCheckin < ActiveRecord::Base
belongs_to :household
has_many :client_checkins

def self.create_for(primary_client)
household = primary_client.household
if household
household_checkin = household.household_checkins.create
@primary_checkin_id = ClientCheckin.create_collection(primary_client, household.clients, household_checkin)
def self.extract_attributes_from_docs(docs)
docs.inject({}) do |hash, doc|
hash[doc['doctype'] + '_warn'] = doc['warned']
hash['household_id'] ||= doc['association_id']
hash
end
@primary_checkin_id
end

def primary_client_checkin
Expand Down
115 changes: 115 additions & 0 deletions spec/models/checkin_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
require 'spec_helper'

describe Checkin do
context ".new method with client attribute" do
context "client has no household" do
let(:client){ FactoryGirl.create(:client) }
it { expect{ Checkin.new(:client => client) }.to raise_error(Checkin::InvalidClientError) }
it { expect{ Checkin.new(:client => Household.new) }.to raise_error(Checkin::InvalidClientError) }
end

context "client has associated household" do
let(:client){ FactoryGirl.create(:client) }
let(:household){ FactoryGirl.create(:household) }
let(:checkin){ Checkin.new(:client => client) }
before { household.clients << client }
it { expect{ Checkin.new(:client => client )}.not_to raise_error }

it 'should have an unpersisted household_checkin' do
checkin.household_checkin.new_record?.should == true
end

it 'should associate the household_checkin with the household' do
checkin.household_checkin.household_id.should == household.id
end

it 'should have an array of client_checkins' do
checkin.client_checkins.should be_a(Array)
checkin.client_checkins.each { |cc| cc.should be_a(ClientCheckin) }
end

it 'should have a household object' do
checkin.household.should == household
end
end
end

context '.new method with household_checkin attribute' do
context 'household_checkin is not a HouseholdCheckin object' do
let(:household_checkin){ "not a HouseholdCheckin object" }
it{ expect{ Checkin.new(:household_checkin => household_checkin) }.to raise_error(Checkin::InvalidHouseholdCheckinError)}
end

context 'household_checkin is a valid HouseholdCheckin' do
let(:household){ FactoryGirl.create(:household) }
let(:client){ FactoryGirl.create(:client, :household_id => household) }
let(:household_checkin){ HouseholdCheckin.create(:household => household) }
let(:checkin){ Checkin.new(:household_checkin => household_checkin ) }
it{ expect{ Checkin.new(:household_checkin => household_checkin) }.not_to raise_error}

it 'should store the passed-in HouseholdCheckin in its household_checkin variable' do
checkin.household_checkin.should == household_checkin
end
end
end

describe '.find_by_client_checkin_id' do
let(:household){ FactoryGirl.create(:household) }
let(:client){ FactoryGirl.create(:client, :household_id => household.id) }
let(:household_checkin){ HouseholdCheckin.create(:household_id => household.id) }
let(:client_checkin){ ClientCheckin.create(:client_id => client.id, :household_checkin_id => household_checkin.id) }
before do
@checkin = Checkin.find_by_client_checkin_id(client_checkin.id)
end

it "should have an existing HouseholdCheckin object" do
@checkin.household_checkin.should == household_checkin
@checkin.household_checkin.new_record?.should == false
end

it "should have existing ClientCheckin objects" do
@checkin.client_checkins.should == [client_checkin]
end
end

describe '#save method' do
context 'when client_checkins and household_checkins already existed' do
let(:household){ FactoryGirl.create(:household) }
let(:client){ FactoryGirl.create(:client, :household_id => household.id) }
let(:household_checkin){ HouseholdCheckin.create(:household_id => household.id) }
let(:client_checkin){ ClientCheckin.create(:client_id => client.id, :household_checkin_id => household_checkin.id) }
before do
checkin = Checkin.find_by_client_checkin_id(client_checkin.id)
checkin.save
end

it 'should save a client_checkin for the client' do
ClientCheckin.count.should == 1
end

it 'should save a household_checkin for the clients household' do
HouseholdCheckin.count.should == 1
end
end

context 'when client_checkins and household_checkins did not previously exist' do
let(:household){ FactoryGirl.create(:household) }
let(:client){ FactoryGirl.create(:client, :household_id => household.id) }
before do
Checkin.create(client)
end

it 'should save a client_checkin for the client' do
ClientCheckin.count.should == 1
end

it 'should associate its client_checkin with its household_checkin' do
ClientCheckin.first.household_checkin_id.should == HouseholdCheckin.first.id
end

it 'should save a household_checkin for the clients household' do
HouseholdCheckin.count.should == 1
end
end
end
end

0 comments on commit ac76cbf

Please sign in to comment.