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.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: