activerecord_chronological_records 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "activerecord_chronological_records"
8
- s.version = "0.2.0"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Toms Mikoss"]
12
- s.date = "2012-11-13"
12
+ s.date = "2012-11-14"
13
13
  s.description = "Provides a set of helper methods for dealing with chronological records that have common primary key and date columns denoting when the record is active (example: Oracle EBS tables)."
14
14
  s.email = "toms.mikoss@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -6,9 +6,15 @@ module ActiverecordChronologicalRecords
6
6
  start_column, end_column = options[0], options[1]
7
7
  end
8
8
 
9
+ dealing_with_dates = columns.select{|c| [start_column, end_column].map(&:to_s).include? c.name}.all?{|c| c.type == :date}
10
+
11
+ query_start_column = "#{table_name}.#{start_column}"
12
+ query_end_column = "#{table_name}.#{end_column}"
13
+ same_record_lookup = "#{self}.where(:#{primary_key} => self.#{primary_key})"
14
+
9
15
  self.instance_eval <<-EOS
10
16
  def effective_at(date)
11
- where("(#{start_column} <= :date OR #{start_column} IS NULL) AND (#{end_column} >= :date OR #{end_column} IS NULL)", :date => date)
17
+ where("(#{query_start_column} <= :date OR #{query_start_column} IS NULL) AND (#{query_end_column} >= :date OR #{query_end_column} IS NULL)", :date => #{dealing_with_dates ? 'date.to_date' : 'date'})
12
18
  end
13
19
 
14
20
  def current
@@ -18,23 +24,15 @@ EOS
18
24
 
19
25
  self.class_eval <<-EOS
20
26
  def effective_at(date)
21
- #{self}.effective_at(date).where(:#{primary_key} => self.#{primary_key}).first
22
- end
23
-
24
- def current
25
- effective_at(Time.now)
26
- end
27
-
28
- def current?
29
- (#{start_column}.blank? || #{start_column}.to_time <= Time.now) && (#{end_column}.blank? || #{end_column}.to_time >= Time.now)
27
+ #{same_record_lookup}.effective_at(date).first
30
28
  end
31
29
 
32
30
  def earliest
33
- #{self}.where(:#{primary_key} => self.#{primary_key}).order("#{start_column} ASC").first
31
+ #{same_record_lookup}.order("#{query_start_column} ASC").first
34
32
  end
35
33
 
36
34
  def latest
37
- #{self}.where(:#{primary_key} => self.#{primary_key}).order("#{start_column} DESC").first
35
+ #{same_record_lookup}.order("#{query_start_column} DESC").first
38
36
  end
39
37
 
40
38
  def previous
@@ -44,6 +42,14 @@ EOS
44
42
  def next
45
43
  effective_at(#{end_column} + 1.day)
46
44
  end
45
+
46
+ def current
47
+ effective_at(Time.now)
48
+ end
49
+
50
+ def current?
51
+ (#{start_column}.blank? || #{start_column}.to_time <= Time.now) && (#{end_column}.blank? || #{end_column}.to_time >= Time.now)
52
+ end
47
53
  EOS
48
54
  end
49
55
  end
@@ -1,29 +1,22 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- describe "ActiverecordChronologicalRecords" do
3
+ describe ActiverecordChronologicalRecords do
4
4
  def make_employee(attributes)
5
5
  Employee.new(attributes).tap{ |e| e.id = 1; e.save! }
6
6
  end
7
7
 
8
- before(:all) do
9
- Employee.rebuild_table do |t|
10
- t.date :start_date
11
- t.date :end_date
12
- end
13
-
14
- Employee.has_chronological_records
15
- end
16
-
17
8
  shared_examples "scopes" do
18
9
  specify { Employee.current.all.should eq [@current_record] }
19
- specify { Employee.effective_at(Date.today).all.should eq [@current_record] }
20
- specify { Employee.effective_at(Date.today - 2.months).all.should eq [@first_record] }
21
- specify { Employee.effective_at(Date.today + 2.months).all.should eq [@last_record] }
10
+ specify { Employee.effective_at(Date.today).should eq [@current_record] }
11
+ specify { Employee.effective_at(Date.today - 2.months).should eq [@first_record] }
12
+ specify { Employee.effective_at(Date.today + 2.months).should eq [@last_record] }
13
+ specify { Employee.effective_at(Date.today - 2.years).should be_empty }
22
14
  end
23
15
 
24
16
  shared_examples "navigation methods" do
25
17
  specify { @first_record.current.should eq @current_record }
26
18
  specify { @first_record.effective_at(Date.today).should eq @current_record }
19
+ specify { @first_record.effective_at(Date.today - 2.years).should be_nil }
27
20
  specify { @current_record.earliest.should eq @first_record }
28
21
  specify { @current_record.latest.should eq @last_record }
29
22
  specify { @current_record.previous.should eq @first_record }
@@ -37,7 +30,7 @@ describe "ActiverecordChronologicalRecords" do
37
30
 
38
31
  context "When start and end dates are present" do
39
32
  before(:all) do
40
- Employee.destroy_all
33
+ Employee.delete_all
41
34
  @first_record = make_employee(:start_date => Date.today - 1.year, :end_date => Date.today - 1.month - 1.day)
42
35
  @current_record = make_employee(:start_date => Date.today - 1.month, :end_date => Date.today + 1.month)
43
36
  @last_record = make_employee(:start_date => Date.today + 1.month + 1.day, :end_date => Date.today + 1.year)
@@ -46,11 +39,13 @@ describe "ActiverecordChronologicalRecords" do
46
39
  include_examples "scopes"
47
40
  include_examples "navigation methods"
48
41
  include_examples "helper methods"
42
+
43
+ specify { Employee.effective_at(Date.today + 1.year + 1.day).should be_empty }
49
44
  end
50
45
 
51
46
  context "When last record does not have end date" do
52
47
  before(:all) do
53
- Employee.destroy_all
48
+ Employee.delete_all
54
49
  @first_record = make_employee(:start_date => Date.today - 1.year, :end_date => Date.today - 1.month - 1.day)
55
50
  @current_record = make_employee(:start_date => Date.today - 1.month, :end_date => Date.today + 1.month)
56
51
  @last_record = make_employee(:start_date => Date.today + 1.month + 1.day, :end_date => nil)
@@ -60,4 +55,39 @@ describe "ActiverecordChronologicalRecords" do
60
55
  include_examples "navigation methods"
61
56
  include_examples "helper methods"
62
57
  end
58
+
59
+ context "when used in join and colums with same name are defined on both tables" do
60
+ before(:all) do
61
+ Project.delete_all
62
+ Employee.delete_all
63
+
64
+ @project = Project.create
65
+
66
+ @first_record = make_employee(:project => @project, :start_date => Date.today - 1.year, :end_date => Date.today - 1.month - 1.day)
67
+ @current_record = make_employee(:project => @project, :start_date => Date.today - 1.month, :end_date => Date.today + 1.month)
68
+ end
69
+
70
+ specify { expect { @project.employees.current.all }.not_to raise_error }
71
+ specify { Employee.joins(:project).current.should eq [@current_record] }
72
+ specify { Employee.joins(:project).effective_at(Date.today - 2.months).should eq [@first_record] }
73
+ end
74
+
75
+ context "dealing with inclusion" do
76
+ before do
77
+ Employee.delete_all
78
+ Mood.delete_all
79
+ end
80
+
81
+ it "when end_date is date, current scope should include records that end today" do
82
+ employee = make_employee(:start_date => Date.today - 1.day, :end_date => Date.today)
83
+ sleep 1
84
+ Employee.current.should eq [employee]
85
+ end
86
+
87
+ it "when end_date is time, current scope should include records that have ended" do
88
+ mood = Mood.create(:start_time => Time.now - 1.minute, :end_time => Time.now)
89
+ sleep 1
90
+ Mood.current.should be_empty
91
+ end
92
+ end
63
93
  end
@@ -13,17 +13,46 @@ ActiveRecord::Base.establish_connection(
13
13
  :database => "#{File.dirname(__FILE__)}/activerecord_chronological_records.db"
14
14
  )
15
15
 
16
+ ActiveRecord::Schema.define do
17
+ self.verbose = false
18
+
19
+ create_table :projects, :force => true do |t|
20
+ t.date :start_date
21
+ t.date :end_date
22
+ end
23
+
24
+ create_table :employees, :force => true, :id => false do |t|
25
+ t.integer :id
26
+ t.references :project
27
+ t.date :start_date
28
+ t.date :end_date
29
+ end
30
+
31
+ create_table :moods, :force => true, :id => false do |t|
32
+ t.integer :id
33
+ t.references :employee
34
+ t.datetime :start_time
35
+ t.datetime :end_time
36
+ end
37
+ end
38
+
39
+ class Project < ActiveRecord::Base
40
+ has_many :employees
41
+ end
42
+
16
43
  class Employee < ActiveRecord::Base
17
44
  self.primary_key = :id
18
45
 
19
- def self.rebuild_table
20
- ActiveRecord::Schema.define do
21
- self.verbose = false
46
+ belongs_to :project
47
+ has_many :moods
22
48
 
23
- create_table :employees, :force => true, :id => false do |t|
24
- t.integer :id
25
- yield t
26
- end
27
- end
28
- end
49
+ has_chronological_records
50
+ end
51
+
52
+ class Mood < ActiveRecord::Base
53
+ self.primary_key = :id
54
+
55
+ belongs_to :employee
56
+
57
+ has_chronological_records :start_time, :end_time
29
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord_chronological_records
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-13 00:00:00.000000000 Z
12
+ date: 2012-11-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -144,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
144
  version: '0'
145
145
  segments:
146
146
  - 0
147
- hash: -126950927
147
+ hash: 829829455
148
148
  required_rubygems_version: !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements: