periodic_records 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +30 -0
- data/lib/periodic_records/model.rb +31 -31
- data/lib/periodic_records/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 517b17390003ad69bdd1df93b29302b22056f914
|
4
|
+
data.tar.gz: 0e7fe3fa98fa5ac0bcb740aded5f648de6a53a34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 608187e68129461db42bb131a9734502109068ae2946dab474ed413208f6d3dfbd8a6f2923fb0d7725316683ab50a43b28af5885e8e9a0e4313d8241644f40f2
|
7
|
+
data.tar.gz: 6934f812a9a02eb33128aa8b7996c2c3d057a3b8e5e66dd83f1b9512b14b3b97544f00c301a6871e679d463f6b0af62da2b2623f013f1f8024941aac8ed7245e
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
5
5
|
|
6
|
+
## [0.2.0] - 2016-04-08
|
7
|
+
|
8
|
+
- Use before_save for adjust_overlapping_records so that it works with
|
9
|
+
database constraints
|
10
|
+
- Fixed spelling for methods (overlaping -> overlapping)
|
11
|
+
|
6
12
|
## [0.1.1] - 2015-11-09
|
7
13
|
|
8
14
|
- Fix preloading with rails 4.2
|
data/README.md
CHANGED
@@ -121,6 +121,36 @@ employees.each do |employee|
|
|
121
121
|
end
|
122
122
|
```
|
123
123
|
|
124
|
+
## Database Constraints
|
125
|
+
|
126
|
+
To avoid inconsistent data in race conditions, you can add database constraint
|
127
|
+
that checks overlapping periods.
|
128
|
+
|
129
|
+
Postgres:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
class AddEmployeeAssignmentsOverlappingDatesConstraint < ActiveRecord::Migration
|
133
|
+
def up
|
134
|
+
execute "CREATE EXTENSION IF NOT EXISTS btree_gist"
|
135
|
+
execute <<-SQL
|
136
|
+
ALTER TABLE employee_assignments
|
137
|
+
ADD CONSTRAINT employee_assignments_overlapping_dates
|
138
|
+
EXCLUDE USING GIST(
|
139
|
+
employee_id WITH =,
|
140
|
+
TSRANGE(start_at, end_at) WITH &&
|
141
|
+
)
|
142
|
+
SQL
|
143
|
+
end
|
144
|
+
|
145
|
+
def down
|
146
|
+
execute <<-SQL.squish
|
147
|
+
ALTER TABLE employee_assignments
|
148
|
+
DROP CONSTRAINT employee_assignments_overlapping_dates
|
149
|
+
SQL
|
150
|
+
end
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
124
154
|
## Development
|
125
155
|
|
126
156
|
After checking out the repo, run `bin/setup` to install dependencies.
|
@@ -10,7 +10,7 @@ module PeriodicRecords
|
|
10
10
|
validate :validate_dates
|
11
11
|
|
12
12
|
after_initialize :set_default_period, if: :set_default_period_after_initialize?
|
13
|
-
|
13
|
+
before_save :adjust_overlapping_records
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
@@ -48,22 +48,22 @@ module PeriodicRecords
|
|
48
48
|
raise NotImplementedError
|
49
49
|
end
|
50
50
|
|
51
|
-
def
|
52
|
-
@
|
51
|
+
def overlapping_records
|
52
|
+
@overlapping_records ||= siblings.within_interval(start_at, end_at)
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
56
|
-
|
57
|
-
if
|
58
|
-
|
59
|
-
|
60
|
-
elsif
|
61
|
-
|
62
|
-
|
63
|
-
elsif
|
64
|
-
|
65
|
-
elsif
|
66
|
-
|
55
|
+
def adjust_overlapping_records
|
56
|
+
overlapping_records.each do |overlapping_record|
|
57
|
+
if overlapping_record.start_at >= start_at &&
|
58
|
+
overlapping_record.end_at <= end_at
|
59
|
+
destroy_overlapping_record(overlapping_record)
|
60
|
+
elsif overlapping_record.start_at < start_at &&
|
61
|
+
overlapping_record.end_at > end_at
|
62
|
+
split_overlapping_record(overlapping_record)
|
63
|
+
elsif overlapping_record.start_at < start_at
|
64
|
+
adjust_overlapping_record_end_at(overlapping_record)
|
65
|
+
elsif overlapping_record.end_at > end_at
|
66
|
+
adjust_overlapping_record_start_at(overlapping_record)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
@@ -79,30 +79,30 @@ module PeriodicRecords
|
|
79
79
|
self.end_at ||= MAX
|
80
80
|
end
|
81
81
|
|
82
|
-
def
|
83
|
-
|
82
|
+
def destroy_overlapping_record(overlapping_record)
|
83
|
+
overlapping_record.destroy
|
84
84
|
end
|
85
85
|
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
def split_overlapping_record(overlapping_record)
|
87
|
+
overlapping_record_end = overlapping_record.dup
|
88
|
+
overlapping_record_end.start_at = end_at + 1.day
|
89
|
+
overlapping_record_end.end_at = overlapping_record.end_at
|
90
90
|
|
91
|
-
|
92
|
-
|
91
|
+
overlapping_record_start = overlapping_record
|
92
|
+
overlapping_record_start.end_at = start_at - 1.day
|
93
93
|
|
94
|
-
|
95
|
-
|
94
|
+
overlapping_record_start.save(validate: false)
|
95
|
+
overlapping_record_end.save(validate: false)
|
96
96
|
end
|
97
97
|
|
98
|
-
def
|
99
|
-
|
100
|
-
|
98
|
+
def adjust_overlapping_record_end_at(overlapping_record)
|
99
|
+
overlapping_record.end_at = start_at - 1.day
|
100
|
+
overlapping_record.save(validate: false)
|
101
101
|
end
|
102
102
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
103
|
+
def adjust_overlapping_record_start_at(overlapping_record)
|
104
|
+
overlapping_record.start_at = end_at + 1.day
|
105
|
+
overlapping_record.save(validate: false)
|
106
106
|
end
|
107
107
|
|
108
108
|
def validate_dates
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: periodic_records
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edgars Beigarts
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|