activerecord_chronological_records 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
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.
|
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-
|
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("(#{
|
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
|
-
#{
|
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
|
-
#{
|
31
|
+
#{same_record_lookup}.order("#{query_start_column} ASC").first
|
34
32
|
end
|
35
33
|
|
36
34
|
def latest
|
37
|
-
#{
|
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
|
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).
|
20
|
-
specify { Employee.effective_at(Date.today - 2.months).
|
21
|
-
specify { Employee.effective_at(Date.today + 2.months).
|
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.
|
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.
|
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
|
data/spec/spec_helper.rb
CHANGED
@@ -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
|
-
|
20
|
-
|
21
|
-
self.verbose = false
|
46
|
+
belongs_to :project
|
47
|
+
has_many :moods
|
22
48
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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.
|
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-
|
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:
|
147
|
+
hash: 829829455
|
148
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
149
|
none: false
|
150
150
|
requirements:
|