timely 0.5.0 → 0.6.0

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -2
  3. data/.travis.yml +0 -6
  4. data/CHANGELOG.md +6 -0
  5. data/Gemfile +2 -0
  6. data/Rakefile +6 -4
  7. data/gemfiles/rails5.gemfile +4 -2
  8. data/gemfiles/rails6.gemfile +3 -1
  9. data/lib/timely/date.rb +6 -2
  10. data/lib/timely/date_chooser.rb +29 -30
  11. data/lib/timely/date_range.rb +17 -19
  12. data/lib/timely/date_time.rb +3 -1
  13. data/lib/timely/rails/calendar_tag.rb +3 -3
  14. data/lib/timely/rails/date.rb +3 -1
  15. data/lib/timely/rails/date_group.rb +24 -24
  16. data/lib/timely/rails/date_range_validity_module.rb +8 -6
  17. data/lib/timely/rails/date_time.rb +5 -3
  18. data/lib/timely/rails/extensions.rb +12 -37
  19. data/lib/timely/rails/period.rb +14 -12
  20. data/lib/timely/rails/season.rb +14 -33
  21. data/lib/timely/rails/time.rb +7 -3
  22. data/lib/timely/rails.rb +2 -0
  23. data/lib/timely/railtie.rb +2 -0
  24. data/lib/timely/range.rb +4 -2
  25. data/lib/timely/string.rb +4 -2
  26. data/lib/timely/time.rb +7 -3
  27. data/lib/timely/time_since.rb +5 -3
  28. data/lib/timely/trackable_date_set.rb +21 -21
  29. data/lib/timely/version.rb +3 -1
  30. data/lib/timely/week_days.rb +14 -16
  31. data/lib/timely.rb +2 -0
  32. data/rails/init.rb +2 -0
  33. data/spec/calendar_tag_spec.rb +11 -10
  34. data/spec/date_chooser_spec.rb +67 -62
  35. data/spec/date_group_spec.rb +18 -15
  36. data/spec/date_range_spec.rb +29 -19
  37. data/spec/date_spec.rb +3 -1
  38. data/spec/extensions_spec.rb +5 -9
  39. data/spec/rails/date_spec.rb +5 -3
  40. data/spec/rails/date_time_spec.rb +9 -7
  41. data/spec/rails/period_spec.rb +2 -0
  42. data/spec/rails/time_spec.rb +6 -4
  43. data/spec/schema.rb +4 -3
  44. data/spec/season_spec.rb +23 -26
  45. data/spec/spec_helper.rb +3 -1
  46. data/spec/support/coverage_loader.rb +3 -1
  47. data/spec/temporal_patterns_spec.rb +5 -5
  48. data/spec/time_since_spec.rb +6 -4
  49. data/spec/time_spec.rb +6 -4
  50. data/spec/trackable_date_set_spec.rb +20 -18
  51. data/spec/week_days_spec.rb +24 -22
  52. data/timely.gemspec +20 -18
  53. metadata +32 -20
  54. data/spec/string_spec.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e311a6b7b3b8f1c2c118f67e3cddc6ef7592091514c64f99c7a8d1f46f617d7a
4
- data.tar.gz: ae6d6fa3c929fe97a63ed3e907544e97cafb38d2dc768f95d5cea00057d07864
3
+ metadata.gz: 6fd5bf30099265da88c4957079fd58a4db290fac8cd4ad239ddb395be546d5d3
4
+ data.tar.gz: d263dca100292aae36f54b22cc2f3b1eebc1c1df0274fc3ef730ce991fc94c4a
5
5
  SHA512:
6
- metadata.gz: 4f0f48ab52cb955cd0dcc13b89138cc72dc5b444f87589173d346595d822bb12c205a5c93a27c34e5a5ea765807d521931823bd331c4baefa30a48a34e516829
7
- data.tar.gz: 7013bcafe2fbed12b92caf1fc9da3b07292050fd643cd05a975495674cf5fbd206c815a4d9e65dafbbc25d2af8fb0c646f40a4cf839e4e8a03c08b1b795ec5d6
6
+ metadata.gz: 784aede0c406afe8e0213f275150ee3bba930969c28acf9ac2e992a96ce42c7f30e042a6e0ae9779dc17f86e6a7744c4b0a07bf72e1d326d6e6176b3ac4b28c4
7
+ data.tar.gz: a780a85c02adcf074c53376c7995739d609329256b76c370966bedaccf953e0e3cb7607cb0d381873a8a4585b48505c8d2d04f68bebdc94f0b49c947bab84d28
data/.rubocop.yml CHANGED
@@ -1,8 +1,28 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ Exclude:
4
+ - lib/timely/temporal_patterns/*.rb
5
+
1
6
  Metrics/LineLength:
2
- Max: 80
7
+ Max: 200
3
8
 
4
9
  Style/Documentation:
5
10
  Enabled: false
6
11
 
7
12
  Style/FrozenStringLiteralComment:
8
- Enabled: false # Using Ruby 2.4 doesn't need it
13
+ Enabled: true
14
+
15
+ Metrics/BlockLength:
16
+ Enabled: false
17
+
18
+ Metrics/MethodLength:
19
+ Enabled: false
20
+
21
+ Metrics/AbcSize:
22
+ Enabled: false
23
+
24
+ Metrics/CyclomaticComplexity:
25
+ Enabled: false
26
+
27
+ Metrics/PerceivedComplexity:
28
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,14 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.4
4
- - 2.5
5
3
  - 2.6
6
4
  matrix:
7
5
  fast_finish: true
8
- exclude:
9
- - rvm: 2.4
10
- gemfile: gemfiles/rails6.gemfile
11
-
12
6
  before_install:
13
7
  - gem install bundler
14
8
  script: bundle exec rake spec
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0
4
+
5
+ * [TT-6402] Require date group weekdays bit field to be not null/nil
6
+ IMPORTANT: Rails projects must add a migration to make this field not null!
7
+ * [TT-6401] Remove Rails 3 support, unused methods
8
+
3
9
  ## 0.5.0
4
10
 
5
11
  * [TT-6193] Date group scopes for more efficient searches/restrictions
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
  gemspec
data/Rakefile CHANGED
@@ -1,12 +1,14 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
2
4
 
3
5
  desc 'Default: run specs.'
4
- task :default => :spec
6
+ task default: :spec
5
7
 
6
8
  require 'rspec/core/rake_task'
7
9
 
8
- desc "Run specs"
10
+ desc 'Run specs'
9
11
  RSpec::Core::RakeTask.new do |t|
10
- t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
12
+ t.pattern = './spec/**/*_spec.rb' # don't need this, it's default.
11
13
  # Put spec opts in a file named .rspec in root
12
14
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
- gemspec :path => '../'
4
+ gemspec path: '../'
3
5
 
4
6
  group :development, :test do
5
- gem 'activerecord', '~> 5.0'
7
+ gem 'activerecord', '~> 5.2'
6
8
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
- gemspec :path => '../'
4
+ gemspec path: '../'
3
5
 
4
6
  group :development, :test do
5
7
  gem 'activerecord', '~> 6.0.0.rc1'
data/lib/timely/date.rb CHANGED
@@ -1,15 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  module Date
3
5
  def at_time(hour = nil, minute = nil, second = nil)
4
6
  if hour.is_a?(::Time)
5
7
  time = hour
6
- hour, minute, second = time.hour, time.min, time.sec
8
+ hour = time.hour
9
+ minute = time.min
10
+ second = time.sec
7
11
  end
8
12
 
9
13
  ::Time.local(year, month, day, hour, minute, second)
10
14
  end
11
15
 
12
- alias_method :at, :at_time
16
+ alias at at_time
13
17
 
14
18
  # returns true if date between from and to
15
19
  # however if from and/or to are nil, it ignores that query
@@ -1,18 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  class DateChooser
3
5
  # Where is this used... so far only in one place, _date_range.html.haml
4
6
  # May be good to refactor this as well, after the class behaviour is refactored.
5
7
  INTERVALS = [
6
- {:code => 'week', :name => 'week(s)', :description =>
7
- 'Weekdays selected will be chosen every {{n}} weeks for the date range'},
8
- {:code => 'week_of_month', :name => 'week of month', :description =>
9
- 'Weekdays selected will be chosen in their {{ord}} occurance every month,
8
+ { code: 'week', name: 'week(s)', description: 'Weekdays selected will be chosen every {{n}} weeks for the date range' },
9
+ { code: 'week_of_month', name: 'week of month', description: 'Weekdays selected will be chosen in their {{ord}} occurance every month,
10
10
  e.g. if wednesday and thursday are selected, the first wednesday and
11
11
  first thursday are selected. Note: this may mean the booking is copied
12
- to Thursday 1st and Wednesday 7th'}
13
- ]
12
+ to Thursday 1st and Wednesday 7th' }
13
+ ].freeze
14
14
 
15
- attr_accessor :multiple_dates, :from, :to, :select, :dates, :interval, :weekdays
15
+ attr_accessor :multiple_dates, :from, :to, :select, :dates, :interval, :weekdays
16
16
 
17
17
  def initialize(options)
18
18
  @multiple_dates = options[:multiple_dates] || false
@@ -28,8 +28,8 @@ module Timely
28
28
 
29
29
  def process_date(date)
30
30
  case date
31
- when Date; date
32
- when NilClass; nil
31
+ when Date then date
32
+ when NilClass then nil
33
33
  when String
34
34
  date !~ /[^[:space:]]/ ? nil : date.to_date
35
35
  end
@@ -53,7 +53,7 @@ module Timely
53
53
  # so every friday and saturday each fornight
54
54
  def choose_dates
55
55
  # Not multiple dates - just return the From date.
56
- return [@from] if !@multiple_dates
56
+ return [@from] unless @multiple_dates
57
57
 
58
58
  # Multiple dates - return the array, adjusted as per input
59
59
  all_days = (@from..@to).to_a
@@ -66,21 +66,21 @@ module Timely
66
66
  days = @specific_dates.gsub(/\s/, '').split(',')
67
67
  days.map(&:to_date)
68
68
  when 'weekdays'
69
- raise DateChooserException, "No days of the week selected" if @weekdays.weekdays.empty?
70
- raise DateChooserException, "No weekly interval selected" if @interval && @interval.empty?
69
+ raise DateChooserException, 'No days of the week selected' if @weekdays.weekdays.empty?
70
+ raise DateChooserException, 'No weekly interval selected' if @interval&.empty?
71
71
 
72
72
  all_days.select do |date|
73
- if @weekdays.has_day?(date.wday)
74
- case @interval[:unit]
75
- when 'week'
76
- # 0 = first week, 1 = second week, 2 = third week, etc.
77
- nth_week = (date - @from).to_i / 7
78
- # true every 2nd week (0, 2, 4, 6, etc.)
79
- (nth_week % @interval[:level].to_i).zero?
80
- when 'week_of_month'
81
- week = @interval[:level].to_i
82
- (date.mday > (week-1)*7 && date.mday <= week*7)
83
- end
73
+ next unless @weekdays.has_day?(date.wday)
74
+
75
+ case @interval[:unit]
76
+ when 'week'
77
+ # 0 = first week, 1 = second week, 2 = third week, etc.
78
+ nth_week = (date - @from).to_i / 7
79
+ # true every 2nd week (0, 2, 4, 6, etc.)
80
+ (nth_week % @interval[:level].to_i).zero?
81
+ when 'week_of_month'
82
+ week = @interval[:level].to_i
83
+ (date.mday > (week - 1) * 7 && date.mday <= week * 7)
84
84
  end
85
85
  end
86
86
  else
@@ -89,15 +89,14 @@ module Timely
89
89
  end
90
90
 
91
91
  private
92
+
92
93
  def validate
93
- if !@from
94
- raise DateChooserException, "A Start Date is required"
95
- elsif @multiple_dates
96
- @to ||= @from
97
- raise DateChooserException, "Start Date is after End Date" if @from > @to
98
- end
94
+ raise DateChooserException, 'A Start Date is required' unless @from
95
+ raise DateChooserException, 'Start Date is after End Date' if @multiple_dates && @to && @from > @to
96
+
97
+ @to ||= @from if @multiple_dates
99
98
  end
100
99
  end
101
100
 
102
- class DateChooserException < Exception; end
101
+ class DateChooserException < RuntimeError; end
103
102
  end
@@ -1,4 +1,4 @@
1
- require 'date' # Ensure Date class is loaded for old rubies (1.8)
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Timely
4
4
  class DateRange < ::Range
@@ -15,14 +15,14 @@ module Timely
15
15
  super(args.first.to_date, args.last.to_date)
16
16
  end
17
17
  end
18
- alias_method :start_date, :first
19
- alias_method :end_date, :last
18
+ alias start_date first
19
+ alias end_date last
20
20
 
21
21
  def self.validate_range(first, last)
22
- raise ArgumentError, "Date range missing start date" if first.nil?
23
- raise ArgumentError, "Date range missing end date" if last.nil?
24
- raise ArgumentError, "Start date is not a date" unless first.is_a? Date
25
- raise ArgumentError, "End date is not a date" unless last.is_a? Date
22
+ raise ArgumentError, 'Date range missing start date' if first.nil?
23
+ raise ArgumentError, 'Date range missing end date' if last.nil?
24
+ raise ArgumentError, 'Start date is not a date' unless first.is_a? Date
25
+ raise ArgumentError, 'End date is not a date' unless last.is_a? Date
26
26
  end
27
27
 
28
28
  def self.from_params(start_date, duration = nil)
@@ -33,19 +33,18 @@ module Timely
33
33
  end
34
34
 
35
35
  def intersecting_dates(date_range)
36
- start_of_intersection = [self.start_date, date_range.first].max
37
- end_of_intersection = [self.end_date, date_range.last].min
38
- intersection = if end_of_intersection >= start_of_intersection
39
- (start_of_intersection..end_of_intersection)
40
- else
41
- []
42
- end
36
+ r_start = [start_date, date_range.first].max
37
+ r_end = [end_date, date_range.last].min
38
+
39
+ return [] if r_end < r_start
40
+
41
+ r_start..r_end
43
42
  end
44
43
 
45
44
  def number_of_nights
46
45
  ((last - first) + 1).to_i
47
46
  end
48
- alias_method :duration, :number_of_nights
47
+ alias duration number_of_nights
49
48
 
50
49
  def to_s(fmt = '%b %Y', date_fmt = '%Y-%m-%d')
51
50
  Timely::DateRange.to_s(first, last, fmt, date_fmt)
@@ -65,21 +64,20 @@ module Timely
65
64
  "#{first.strftime(month_fmt)} to #{last.strftime(month_fmt)}"
66
65
  end
67
66
  else
68
- "#{first.strftime(fmt)} to #{last.strftime(fmt)}#{" (inclusive)" if is_date}"
67
+ "#{first.strftime(fmt)} to #{last.strftime(fmt)}#{' (inclusive)' if is_date}"
69
68
  end
70
69
  elsif first
71
70
  "on or after #{first.strftime(fmt)}"
72
71
  elsif last
73
72
  "on or before #{last.strftime(fmt)}"
74
73
  else
75
- "no date range"
74
+ 'no date range'
76
75
  end
77
76
  end
78
77
 
79
-
80
78
  private
81
79
 
82
- def self.default_date_format
80
+ private_class_method def self.default_date_format
83
81
  # ::Date as we want Ruby's Date not Timely::Date
84
82
  date_format = ::Date::DATE_FORMATS[:short] if ::Date.const_defined?('DATE_FORMATS')
85
83
  date_format || '%Y-%m-%d'
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  module DateTime
3
5
  def on_date(date)
4
- self.change(:year => date.year, :month => date.month, :day => date.day)
6
+ change(year: date.year, month: date.month, day: date.day)
5
7
  end
6
8
  end
7
9
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  # Uses Date.current to be more accurate for Rails applications
3
5
  def self.current_date
4
6
  ::Date.respond_to?(:current) ? ::Date.current : ::Date.today
5
7
  end
6
8
 
7
-
8
9
  module ActionViewHelpers
9
10
  module FormTagHelper
10
11
  def calendar_tag(name, value = Timely.current_date, *args)
@@ -24,11 +25,10 @@ module Timely
24
25
  options[:size] ||= 10
25
26
  options[:maxlength] ||= 10
26
27
 
27
- tag(:input, options.merge(:name => name, :type => 'text', :value => value)).html_safe
28
+ tag(:input, options.merge(name: name, type: 'text', value: value)).html_safe
28
29
  end
29
30
  end
30
31
 
31
-
32
32
  module DateHelper
33
33
  def calendar(object_name, method, options = {})
34
34
  value = options[:object] || Timely.current_date
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Date
2
4
  def to_time_in_time_zone
3
- (Time.zone || ActiveSupport::TimeZone["UTC"]).local(self.year, self.month, self.day)
5
+ (Time.zone || ActiveSupport::TimeZone['UTC']).local(year, month, day)
4
6
  end
5
7
  end
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  class DateGroup < ActiveRecord::Base
3
- belongs_to :season, :class_name => 'Timely::Season', optional: true
5
+ belongs_to :season, class_name: 'Timely::Season', optional: true, inverse_of: :date_groups
4
6
 
5
7
  weekdays_field :weekdays
6
8
 
9
+ validates :weekdays_bit_array, presence: true
7
10
  validates_presence_of :start_date, :end_date
8
11
  validate :validate_date_range!
9
12
 
@@ -16,16 +19,12 @@ module Timely
16
19
  # IMPORTANT: Required for correctness in case of string param.
17
20
  dates = Array(date_range)
18
21
  scope = covering_date(dates.first)
19
- if dates.first != dates.last
20
- scope = scope.or(covering_date(dates.last))
21
- end
22
+ scope = scope.or(covering_date(dates.last)) if dates.first != dates.last
22
23
  scope
23
24
  }
24
25
 
25
26
  scope :for_any_weekdays, lambda { |weekdays_int|
26
- weekdays_int = weekdays_int.to_i
27
- where((arel_table[:weekdays_bit_array] & weekdays_int).not_eq(0))
28
- .or(where(weekdays_bit_array: nil))
27
+ where((arel_table[:weekdays_bit_array] & weekdays_int.to_i).not_eq(0))
29
28
  }
30
29
 
31
30
  scope :applying_for_duration, lambda { |date_range|
@@ -43,7 +42,7 @@ module Timely
43
42
  elsif weekdays.all_days?
44
43
  true
45
44
  else
46
- date_range.intersecting_dates(start_date..end_date).any?{|d| weekdays.applies_for_date?(d)}
45
+ date_range.intersecting_dates(start_date..end_date).any? { |d| weekdays.applies_for_date?(d) }
47
46
  end
48
47
  end
49
48
 
@@ -70,30 +69,31 @@ module Timely
70
69
  date_groups = []
71
70
  Array.wrap(patterns).each do |pattern|
72
71
  if pattern.frequency.unit == :weeks
73
- weekdays = pattern.intervals.map { |i| i.first_datetime.wday }.inject({}) do |hash, wday|
72
+ weekdays = pattern.intervals.map { |i| i.first_datetime.wday }.each_with_object({}) do |wday, hash|
74
73
  hash[wday] = 1
75
- hash
76
74
  end
77
75
  date_groups << DateGroup.new(
78
- :start_date => pattern.first_datetime.to_date,
79
- :end_date => pattern.last_datetime.to_date,
80
- :weekdays => weekdays)
76
+ start_date: pattern.first_datetime.to_date,
77
+ end_date: pattern.last_datetime.to_date,
78
+ weekdays: weekdays
79
+ )
81
80
  elsif pattern.frequency.unit == :days && pattern.frequency.duration == 1.day
82
81
  date_groups << DateGroup.new(
83
- :start_date => pattern.first_datetime.to_date,
84
- :end_date => pattern.last_datetime.to_date,
85
- :weekdays => 127)
82
+ start_date: pattern.first_datetime.to_date,
83
+ end_date: pattern.last_datetime.to_date,
84
+ weekdays: 127
85
+ )
86
86
  else
87
87
  pattern.datetimes.each do |datetimes|
88
88
  datetimes.group_by(&:week).values.each do |dates|
89
- weekdays = dates.map(&:wday).inject({}) do |hash, wday|
89
+ weekdays = dates.map(&:wday).each_with_object({}) do |wday, hash|
90
90
  hash[wday] = 1
91
- hash
92
91
  end
93
92
  date_groups << DateGroup.new(
94
- :start_date => dates.min.to_date.beginning_of_week,
95
- :end_date => dates.max.to_date.end_of_week,
96
- :weekdays => weekdays)
93
+ start_date: dates.min.to_date.beginning_of_week,
94
+ end_date: dates.max.to_date.end_of_week,
95
+ weekdays: weekdays
96
+ )
97
97
  end
98
98
  end
99
99
  end
@@ -104,9 +104,9 @@ module Timely
104
104
  private
105
105
 
106
106
  def validate_date_range!
107
- if start_date && end_date && (start_date > end_date)
108
- raise ArgumentError, "Incorrect date range #{start_date} is before #{end_date}"
109
- end
107
+ return unless start_date && end_date && start_date > end_date
108
+
109
+ raise ArgumentError, "Incorrect date range #{start_date} is before #{end_date}"
110
110
  end
111
111
  end
112
112
  end
@@ -1,25 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  module DateRangeValidityModule
3
5
  def self.included(base)
4
6
  base.class_eval do
5
- validates :from, :to, :presence => true
7
+ validates :from, :to, presence: true
6
8
  end
7
9
  end
8
10
 
9
11
  def validity_range
10
- (from .. to)
12
+ (from..to)
11
13
  end
12
14
 
13
15
  def correctness_of_date_range
14
- if (from.present? && to.present?)
15
- errors.add(:base, "Invalid Date Range. From date should be less than or equal to To date") if from > to
16
- end
16
+ return unless from.present? && to.present? && from > to
17
+
18
+ errors.add(:base, 'Invalid Date Range. From date should be less than or equal to To date')
17
19
  end
18
20
 
19
21
  def validity_range_to_s
20
22
  "#{from.to_s(:short)} ~ #{to.to_s(:short)}"
21
23
  end
22
-
24
+
23
25
  def valid_on?(date)
24
26
  validity_range.include?(date)
25
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RailsCoreExtensions
2
4
  module DateTime
3
5
  def advance_considering_calendar(units, num_units)
@@ -5,11 +7,11 @@ module RailsCoreExtensions
5
7
  when :seconds, :minutes, :hours, :days, :weeks, :months, :years
6
8
  advance(units => num_units)
7
9
  when :calendar_days
8
- advance(:days => num_units - 1).end_of_day
10
+ advance(days: num_units - 1).end_of_day
9
11
  when :calendar_months
10
- advance(:months => num_units - 1).end_of_month
12
+ advance(months: num_units - 1).end_of_month
11
13
  when :calendar_years
12
- advance(:years => num_units - 1).end_of_year
14
+ advance(years: num_units - 1).end_of_year
13
15
  end
14
16
  end
15
17
  end
@@ -1,55 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  module Extensions
3
5
  # Add a WeekDays attribute
4
6
  #
5
7
  # By default it will use attribute_bit_array as db field, but this can
6
8
  # be overridden by specifying :db_field => 'somthing_else'
7
- def weekdays_field(attribute, options={})
9
+ def weekdays_field(attribute, options = {})
8
10
  db_field = options[:db_field] || attribute.to_s + '_bit_array'
9
- self.composed_of(attribute,
10
- :class_name => "::Timely::WeekDays",
11
- :mapping => [[db_field, 'weekdays_int']],
12
- :converter => Proc.new {|field| ::Timely::WeekDays.new(field)}
13
- )
11
+ composed_of(attribute,
12
+ class_name: '::Timely::WeekDays',
13
+ mapping: [[db_field, 'weekdays_int']],
14
+ converter: proc { |field| ::Timely::WeekDays.new(field) })
14
15
  end
15
16
 
16
17
  def acts_as_seasonal
17
- belongs_to :season, :class_name => 'Timely::Season', optional: true
18
+ belongs_to :season, class_name: 'Timely::Season', optional: true
18
19
  accepts_nested_attributes_for :season
19
20
  validates_associated :season
20
21
 
21
- if ::ActiveRecord::VERSION::MAJOR >= 3
22
- scope :season_on, lambda { |*args|
23
- date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
24
- joins(:season => :date_groups).where("date_groups.start_date <= ? AND date_groups.end_date >= ?", date, date)
25
- }
26
-
27
- scope :available_from, lambda { |*args|
28
- date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
29
- where("boundary_end >= ?", date)
30
- }
31
- else
32
- named_scope :season_on, lambda { |*args|
33
- date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
34
- {
35
- :joins => {:season => :date_groups},
36
- :conditions => ["date_groups.start_date <= ? AND date_groups.end_date >= ?", date, date]
37
- }
38
- }
39
-
40
- named_scope :available_from, lambda { |*args|
41
- date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
42
- {:conditions => ["boundary_end >= ?", date]}
43
- }
44
- end
45
-
46
22
  before_save do |object|
47
- if object.season
48
- object.boundary_start = object.season.boundary_start
49
- object.boundary_end = object.season.boundary_end
50
- end
23
+ next unless object.season
24
+
25
+ object.boundary_start = object.season.boundary_start
26
+ object.boundary_end = object.season.boundary_end
51
27
  end
52
28
  end
53
29
  end
54
30
  end
55
-
@@ -1,19 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timely
2
4
  class Period
3
5
  attr_reader :number, :units
4
6
 
5
- UNITS = [
6
- :seconds,
7
- :minutes,
8
- :hours,
9
- :days,
10
- :weeks,
11
- :months,
12
- :years,
13
- :calendar_days,
14
- :calendar_months,
15
- :calendar_years
16
- ]
7
+ UNITS = %i[
8
+ seconds
9
+ minutes
10
+ hours
11
+ days
12
+ weeks
13
+ months
14
+ years
15
+ calendar_days
16
+ calendar_months
17
+ calendar_years
18
+ ].freeze
17
19
 
18
20
  def initialize(number, units)
19
21
  @number = number