Skip to content

Instantly share code, notes, and snippets.

@bsodmike
Created March 18, 2012 07:07
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 bsodmike/d9f19f16488bd55e8842 to your computer and use it in GitHub Desktop.
Save bsodmike/d9f19f16488bd55e8842 to your computer and use it in GitHub Desktop.
class Applicant < ActiveRecord::Base
ERROR_RECORD_NOT_FOUND = "Error: RecordNotFound!"
has_many :day_attendances
has_many :days, :through => :day_attendances
has_many :workshop_attendances
has_many :workshop_topics, :through => :workshop_attendances
belongs_to :course
attr_accessible :title, :first_name, :last_name, :civil_id, :email, :phone_number,
:work_place, :job_title, :key_responsibilities, :education_qualifications, :special_dietary_requirements, :certificate_choice, :enrollment_reasons, :comments
attr_accessible :workshop_a1, :workshop_b1, :workshop_b2
attr_accessor :workshop_a1, :workshop_b1, :workshop_b2
WT_ERR = "You need to make a selection to proceed!".html_safe
validates_presence_of :workshop_a1, :message => WT_ERR, :unless => lambda { |r| r.workshop_a1.nil? }
validates_presence_of :workshop_b1, :message => WT_ERR, :unless => lambda { |r| r.workshop_b1.nil? }
validates_presence_of :workshop_b2, :message => WT_ERR, :unless => lambda { |r| r.workshop_b2.nil? }
TITLE = %w(Prof Dr Mr Mrs Ms)
CERTIFICATE_CHOICE = %w(Certificate Diploma MSc)
# before_save :format_name
validates_presence_of :title, :first_name, :last_name, :civil_id, :email, :phone_number,
:work_place, :job_title, :key_responsibilities, :education_qualifications, :certificate_choice, :enrollment_reasons
validates_length_of :first_name, :minimum => 2
validates_length_of :last_name, :minimum => 2
validates :email, :uniqueness => true, :email => true
validates :phone_number, :uniqueness => true,
:length => { :minimum => 8 }, :numericality => { :only_integer => true }
validates :civil_id, :length => { :is => 12 }, :numericality => { :only_integer => true }
default_scope { where(:is_active => true) }
validate :ensure_attendance_selection
validate :prevent_not_attending_abuse
validate :check_workshop_a1_cap
validate :check_workshop_b1_cap
validate :check_workshop_b2_cap
validate :prevent_selecting_same_topic
def fullname
"#{first_name} #{last_name}"
end
def fullname_with_title
"#{title} #{first_name} #{last_name}"
end
private
def prevent_selecting_same_topic
error_trigger = false
if workshop_a1.present? && workshop_a1 != 'skip' &&
workshop_b1.present? && workshop_b1 != 'skip' &&
workshop_b2.present? && workshop_b2 != 'skip'
begin
wta1 = WorkshopTopic.find(workshop_a1)
wtb1 = WorkshopTopic.find(workshop_b1)
wtb2 = WorkshopTopic.find(workshop_b2)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
error_trigger = true if wta1.title == wtb1.title || wta1.title == wtb2.title || wtb1.title == wtb2.title
end
if workshop_a1.present? && workshop_a1 != 'skip' &&
workshop_b1.present? && workshop_b1 != 'skip'
begin
wta1 = WorkshopTopic.find(workshop_a1)
wtb1 = WorkshopTopic.find(workshop_b1)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
error_trigger = true if wta1.title == wtb1.title
end
if workshop_a1.present? && workshop_a1 != 'skip' &&
workshop_b2.present? && workshop_b2 != 'skip'
begin
wta1 = WorkshopTopic.find(workshop_a1)
wtb2 = WorkshopTopic.find(workshop_b2)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
error_trigger = true if wta1.title == wtb2.title
end
if workshop_b1.present? && workshop_b1 != 'skip' &&
workshop_b2.present? && workshop_b2 != 'skip'
begin
wtb1 = WorkshopTopic.find(workshop_b1)
wtb2 = WorkshopTopic.find(workshop_b2)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
error_trigger = true if wtb1.title == wtb2.title
end
errors[:base] << "You cannot attend the same workshop topic! Please <strong>make a different selection</strong>.".html_safe if error_trigger && error_trigger == true
end
def check_workshop_a1_cap
if workshop_a1.present? && workshop_a1 != 'skip'
begin
wt = WorkshopTopic.find(workshop_a1)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
errors.add(:workshop_a1, "Workshop Session 1 is full!") if wt.applicants.count >= wt.capacity
end
end
def check_workshop_b1_cap
if workshop_b1.present? && workshop_b1 != 'skip'
begin
wt = WorkshopTopic.find(workshop_b1)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
errors.add(:workshop_b1, "Workshop Session 2 is full!") if wt.applicants.count >= wt.capacity
end
end
def check_workshop_b2_cap
if workshop_b2.present? && workshop_b2 != 'skip'
begin
wt = WorkshopTopic.find(workshop_b2)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
errors.add(:workshop_b2, "Workshop Session 3 is full!") if wt.applicants.count >= wt.capacity
end
end
def prevent_not_attending_abuse
err_string = "You need to <strong>at least</strong> attend a single Workshop Session.
Please select a topic you wish you attend!".html_safe
ws = WorkshopSession.order(:position)
# if a single session is full, at least one selection needs to be made from the remaining two.
if ws[0].workshop_topics_full?
errors[:base] << err_string if (workshop_b1 == "skip" && workshop_b2 == "skip")
elsif ws[1].workshop_topics_full?
errors[:base] << err_string if (workshop_a1 == "skip" && workshop_b2 == "skip")
elsif ws[2].workshop_topics_full?
errors[:base] << err_string if (workshop_a1 == "skip" && workshop_b1 == "skip")
end
# if both sessions in day 2 are full, at least one selection needs to be made for day 1
if ws[1].workshop_topics_full? && ws[2].workshop_topics_full?
errors[:base] << err_string if (workshop_a1 == "skip")
end
err_string = "You need to <strong>select</strong> a topic to attend!".html_safe
# if two of three sessions are full, a selection needs to be made from the remaining session
if ws[0].workshop_topics_full? \
&& ws[1].workshop_topics_full?
if workshop_b2.present? && workshop_b2 != 'skip'
begin
wt = WorkshopTopic.find(workshop_b2)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
errors.add(:workshop_b2, err_string) if wt.applicants.count >= wt.capacity
else
errors.add(:workshop_b2, err_string)
end
elsif ws[0].workshop_topics_full? \
&& ws[2].workshop_topics_full?
if workshop_b1.present? && workshop_b1 != 'skip'
begin
wt = WorkshopTopic.find(workshop_b1)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
errors.add(:workshop_b1, err_string) if wt.applicants.count >= wt.capacity
else
errors.add(:workshop_b1, err_string)
end
elsif ws[1].workshop_topics_full? \
&& ws[2].workshop_topics_full?
if workshop_a1.present? && workshop_a1 != 'skip'
begin
wt = WorkshopTopic.find(workshop_a1)
rescue ActiveRecord::RecordNotFound
return errors[:base] << ERROR_RECORD_NOT_FOUND
end
errors.add(:workshop_a1, err_string) if wt.applicants.count >= wt.capacity
else
errors.add(:workshop_a1, err_string)
end
end
end
def ensure_attendance_selection
err_string = "You need to <strong>at least</strong> attend a single Workshop Session. Please select a topic you wish you attend!".html_safe
errors[:base] << err_string if (workshop_a1 == "skip" && workshop_b1 == "skip" && workshop_b2 == "skip")
end
end
require 'spec_helper'
describe Applicant do
before(:each) do
@ws0 = Factory :ws
@ws1 = Factory :ws
@ws2 = Factory :ws
end
describe "on selecting Not attending for all" do
it "should raise error" do
wt = Factory(:topic1, :workshop_session => @ws0)
lambda { Factory :applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "skip"}.should raise_error(ActiveRecord::RecordInvalid, \
/Please select a topic you wish you attend!/)
end
end
describe "on not making any selection" do
it "should raise error" do
wt = Factory(:topic1, :workshop_session => @ws0)
lambda { Factory :applicant,
:workshop_a1 => "",
:workshop_b1 => "",
:workshop_b2 => ""}.should raise_error(ActiveRecord::RecordInvalid, \
/You need to make a selection to proceed!/)
end
end
describe "on selecting a single session" do
it "should not raise any errors" do
wt = Factory(:topic1, :workshop_session => @ws0)
lambda { Factory :applicant,
:workshop_a1 => "#{wt.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip"
}.should_not raise_error
end
it "should not raise any errors" do
wt = Factory(:topic1, :workshop_session => @ws1)
lambda { Factory :applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{wt.id}",
:workshop_b2 => "skip"
}.should_not raise_error
end
it "should not raise any errors" do
wt = Factory(:topic1, :workshop_session => @ws2)
lambda { Factory :applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{wt.id}"
}.should_not raise_error
end
end
describe "on two sessions having reached full capacity" do
it "should raise errors if workshop_b2 is 'Not Attended'" do
workshop_a1_topic = Factory(:topic1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:topic2, :workshop_session => @ws1)
workshop_b2_topic = Factory(:topic3, :workshop_session => @ws2)
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "#{workshop_a1_topic.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws0.id,
:workshop_topic_id => workshop_a1_topic.id) }
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{workshop_b1_topic.id}",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws1.id,
:workshop_topic_id => workshop_b1_topic.id) }
lambda { Factory :applicant,
:workshop_b2 => "skip"
}.should raise_error(ActiveRecord::RecordInvalid,\
/a topic to attend!/)
end
it "should not raise errors if workshop_b2 is attended" do
workshop_a1_topic = Factory(:topic1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:topic2, :workshop_session => @ws1)
workshop_b2_topic = Factory(:topic3, :workshop_session => @ws2)
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "#{workshop_a1_topic.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws0.id,
:workshop_topic_id => workshop_a1_topic.id) }
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{workshop_b1_topic.id}",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws1.id,
:workshop_topic_id => workshop_b1_topic.id) }
lambda { Factory :applicant,
:workshop_b2 => "#{workshop_b2_topic.id}"
}.should_not raise_error
end
it "should raise errors if workshop_b1 is 'Not Attended'" do
workshop_a1_topic = Factory(:topic1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:topic2, :workshop_session => @ws1)
workshop_b2_topic = Factory(:topic3, :workshop_session => @ws2)
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "#{workshop_a1_topic.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws0.id,
:workshop_topic_id => workshop_a1_topic.id) }
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{workshop_b2_topic.id}").id,
:workshop_session_id => @ws2.id,
:workshop_topic_id => workshop_b2_topic.id) }
lambda { Factory :applicant,
:workshop_b1 => "skip"
}.should raise_error(ActiveRecord::RecordInvalid,\
/a topic to attend!/)
end
it "should not raise errors if workshop_b1 is attended" do
workshop_a1_topic = Factory(:topic1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:topic2, :workshop_session => @ws1)
workshop_b2_topic = Factory(:topic3, :workshop_session => @ws2)
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "#{workshop_a1_topic.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws0.id,
:workshop_topic_id => workshop_a1_topic.id) }
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{workshop_b2_topic.id}").id,
:workshop_session_id => @ws2.id,
:workshop_topic_id => workshop_b2_topic.id) }
lambda { Factory :applicant,
:workshop_b1 => "#{workshop_b1_topic.id}"
}.should_not raise_error
end
it "should raise errors if workshop_a1 is 'Not Attended'" do
workshop_a1_topic = Factory(:topic1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:topic2, :workshop_session => @ws1)
workshop_b2_topic = Factory(:topic3, :workshop_session => @ws2)
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{workshop_b1_topic.id}",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws1.id,
:workshop_topic_id => workshop_b1_topic.id) }
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{workshop_b2_topic.id}").id,
:workshop_session_id => @ws2.id,
:workshop_topic_id => workshop_b2_topic.id) }
lambda { Factory :applicant,
:workshop_a1 => "skip"
}.should raise_error(ActiveRecord::RecordInvalid,\
/a topic to attend!/)
end
it "should not raise errors if workshop_a1 is attended" do
workshop_a1_topic = Factory(:topic1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:topic2, :workshop_session => @ws1)
workshop_b2_topic = Factory(:topic3, :workshop_session => @ws2)
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{workshop_b1_topic.id}",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws1.id,
:workshop_topic_id => workshop_b1_topic.id) }
2.times { WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{workshop_b2_topic.id}").id,
:workshop_session_id => @ws2.id,
:workshop_topic_id => workshop_b2_topic.id) }
lambda { Factory :applicant,
:workshop_a1 => "#{workshop_a1_topic.id}"
}.should_not raise_error
end
end
describe "on selecting two sessions with the same title" do
# t1, t2, t3 factories are used to indicate different topic id's
# although they each have the same <tt>title</tt>
it "should raise errors to prevent attending topics with the same title" do
workshop_a1_topic = Factory(:t1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:t2, :workshop_session => @ws1)
lambda { Factory :applicant,
:workshop_a1 => "#{workshop_a1_topic.id}",
:workshop_b1 => "#{workshop_b1_topic.id}",
:workshop_b2 => "skip"
}.should raise_error(ActiveRecord::RecordInvalid,\
/You cannot attend the same workshop topic!/)
end
it "should raise errors to prevent attending topics with the same title" do
workshop_a1_topic = Factory(:t1, :workshop_session => @ws0)
workshop_b2_topic = Factory(:t2, :workshop_session => @ws2)
lambda { Factory :applicant,
:workshop_a1 => "#{workshop_a1_topic.id}",
:workshop_b1 => "skip",
:workshop_b2 => "#{workshop_b2_topic.id}"
}.should raise_error(ActiveRecord::RecordInvalid,\
/You cannot attend the same workshop topic!/)
end
it "should raise errors to prevent attending topics with the same title" do
workshop_b1_topic = Factory(:t1, :workshop_session => @ws1)
workshop_b2_topic = Factory(:t2, :workshop_session => @ws2)
lambda { Factory :applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{workshop_b1_topic.id}",
:workshop_b2 => "#{workshop_b2_topic.id}"
}.should raise_error(ActiveRecord::RecordInvalid,\
/You cannot attend the same workshop topic!/)
end
end
describe "on selecting all (three) sessions with the same title" do
it "should raise errors to prevent attending topics with the same title" do
workshop_a1_topic = Factory(:t1, :workshop_session => @ws0)
workshop_b1_topic = Factory(:t2, :workshop_session => @ws1)
workshop_b2_topic = Factory(:t3, :workshop_session => @ws2)
lambda { Factory :applicant,
:workshop_a1 => "#{workshop_a1_topic.id}",
:workshop_b1 => "#{workshop_b1_topic.id}",
:workshop_b2 => "#{workshop_b2_topic.id}"
}.should raise_error(ActiveRecord::RecordInvalid,\
/You cannot attend the same workshop topic!/)
end
end
describe "on reaching full capacity and trying to attend *that* session" do
it "workshop_a1 should raise errors" do
wt = Factory(:topic1, :workshop_session => @ws0)
WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "#{wt.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws0.id,
:workshop_topic_id => wt.id)
WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "#{wt.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip"),
:workshop_session_id => @ws0.id,
:workshop_topic_id => wt.id)
lambda { Factory :applicant,
:workshop_a1 => "#{wt.id}",
:workshop_b1 => "skip",
:workshop_b2 => "skip"
}.should raise_error(ActiveRecord::RecordInvalid, \
/Workshop Session 1 is full!/)
end
it "workshop_b1 should raise errors" do
wt = Factory(:topic1, :workshop_session => @ws1)
WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{wt.id}",
:workshop_b2 => "skip").id,
:workshop_session_id => @ws1.id,
:workshop_topic_id => wt.id)
WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{wt.id}",
:workshop_b2 => "skip"),
:workshop_session_id => @ws1.id,
:workshop_topic_id => wt.id)
lambda { Factory :applicant,
:workshop_a1 => "skip",
:workshop_b1 => "#{wt.id}",
:workshop_b2 => "skip"
}.should raise_error(ActiveRecord::RecordInvalid, \
/Workshop Session 2 is full!/)
end
it "workshop_b2 should raise errors" do
wt = Factory(:topic1, :workshop_session => @ws2)
WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{wt.id}").id,
:workshop_session_id => @ws2.id,
:workshop_topic_id => wt.id)
WorkshopAttendance.create(:applicant_id =>
Factory(:applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{wt.id}"),
:workshop_session_id => @ws2.id,
:workshop_topic_id => wt.id)
lambda { Factory :applicant,
:workshop_a1 => "skip",
:workshop_b1 => "skip",
:workshop_b2 => "#{wt.id}"
}.should raise_error(ActiveRecord::RecordInvalid, \
/Workshop Session 3 is full!/)
end
end
end
FactoryGirl.define do
factory :course do
title "Example title"
start DateTime.civil_from_format(:local,2012,5,16,8,0,0)
duration 1980
published true
end
factory :ws, :class => WorkshopSession do
day_id "0"
position "0"
title "foo"
# after_create { |ws| [
# Factory(:ws_topic1, :workshop_session => ws),
# Factory(:ws_topic2, :workshop_session => ws),
# ]}
end
factory :topic1, :class => WorkshopTopic do
code "A"
title "foo"
capacity 2
end
factory :topic2, :class => WorkshopTopic do
code "B"
title "bar"
capacity 2
end
factory :topic3, :class => WorkshopTopic do
code "C"
title "baz"
capacity 2
end
factory :t1, :class => WorkshopTopic do
code "A"
title "foo"
capacity 2
end
factory :t2, :class => WorkshopTopic do
code "A"
title "foo"
capacity 2
end
factory :t3, :class => WorkshopTopic do
code "A"
title "foo"
capacity 2
end
factory :applicant do
title "Mr"
first_name "Bob"
last_name "Doe"
sequence(:civil_id) {|n| "#{"%12d" % Random.new.rand((10 ** 11)...(10 ** 12))}" }
sequence(:email) {|n| "person#{n}@#{(1..100).to_a.sample}example.com" }
sequence(:phone_number) {|n| "#{"%08d" % Random.new.rand((10 ** 7)...(10 ** 8))}" }
work_place "the office"
job_title "the job title"
key_responsibilities "some text"
special_dietary_requirements "some text"
certificate_choice "some text"
education_qualifications "some text"
enrollment_reasons "some text"
end
factory :user do
sequence(:email) {|n| "person#{n}@#{(1..100).to_a.sample}example.com" }
role "admin"
password "password"
password_confirmation "password"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment