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

When creating database constraint instead of `DATERANGE` use `TSRANGE`.
ivarsb marked this conversation as resolved.
Show resolved Hide resolved

## Gapless records

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

def periodic_increment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can call this periodic_precision? wdyt?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps splitting_step or record_split_step, because it's only used on overlapping record splitting?

use_datetime? ? 0.000001.second : 1.day
ivarsb marked this conversation as resolved.
Show resolved Hide resolved
end

private

def set_default_period
Expand All @@ -89,26 +93,30 @@ 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 + periodic_increment
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 - periodic_increment

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 - periodic_increment
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 + periodic_increment
overlapping_record.save(validate: false)
end

def use_datetime?
%w(start_at end_at).all? { |a| self.class.type_for_attribute(a).type == :datetime }
end

def validate_dates
if start_at && end_at && end_at < start_at
errors.add :end_at, :invalid
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