Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add time sensitive period splitting #4

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -151,6 +151,12 @@ class AddEmployeeAssignmentsOverlappingDatesConstraint < ActiveRecord::Migration
end
```

## Time sensitive records

If you need your records to be split with time component, then set `start_at` and `end_at` columns to `datetime` type.

Use `TSRANGE` instead of `DATERANGE` when creating database constraint.

## Gapless records

If you want to avoid gaps between records, you can include also `PeriodicRecords::Gapless`.
Expand Down
20 changes: 16 additions & 4 deletions lib/periodic_records/model.rb
Expand Up @@ -76,6 +76,18 @@ def periodic_dup
dup
end

def record_split_step
@record_split_step ||= begin
column = self.class.column_for_attribute(:start_at)
if column.type == :datetime
precision = column.precision || 6
Float("1.0e-#{precision}").seconds
else
1.day
end
end
end

private

def set_default_period
Expand All @@ -89,23 +101,23 @@ def destroy_overlapping_record(overlapping_record)

def split_overlapping_record(overlapping_record)
overlapping_record_end = overlapping_record.periodic_dup
overlapping_record_end.start_at = end_at + 1.day
overlapping_record_end.start_at = end_at + record_split_step
overlapping_record_end.end_at = overlapping_record.end_at

overlapping_record_start = overlapping_record
overlapping_record_start.end_at = start_at - 1.day
overlapping_record_start.end_at = start_at - record_split_step

overlapping_record_start.save(validate: false)
overlapping_record_end.save(validate: false)
end

def adjust_overlapping_record_end_at(overlapping_record)
overlapping_record.end_at = start_at - 1.day
overlapping_record.end_at = start_at - record_split_step
overlapping_record.save(validate: false)
end

def adjust_overlapping_record_start_at(overlapping_record)
overlapping_record.start_at = end_at + 1.day
overlapping_record.start_at = end_at + record_split_step
overlapping_record.save(validate: false)
end

Expand Down
2 changes: 1 addition & 1 deletion periodic_records.gemspec
Expand Up @@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency "activerecord", ">= 5.1"
spec.add_runtime_dependency "activesupport", ">= 5.1"

spec.add_development_dependency "bundler", "~> 1.9"
spec.add_development_dependency "bundler", ">= 1.9"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.3"
spec.add_development_dependency "sqlite3"
Expand Down
21 changes: 21 additions & 0 deletions spec/models.rb
Expand Up @@ -15,6 +15,27 @@ def siblings
end
end

class TimeSensitiveEmployee < ActiveRecord::Base
self.table_name = 'employees'

include PeriodicRecords::Associations

has_many :employee_assignments, inverse_of: :employee,
class_name: 'TimeSensitiveEmployeeAssignment',
foreign_key: :employee_id
has_periodic :employee_assignments, as: :assignments
end

class TimeSensitiveEmployeeAssignment < ActiveRecord::Base
include PeriodicRecords::Model

belongs_to :employee

def siblings
self.class.where(employee_id: employee_id).where.not(id: id)
end
end

class GaplessEmployee < ActiveRecord::Base
self.table_name = 'employees'

Expand Down