timely 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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