acts_as_living 0.1.0 → 0.1.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de0cdd11d713c73fa97d94da8f0812ffbeeb5bf7b724c86a8f6d1fa01cf79ebc
4
- data.tar.gz: fa9f2638f6e04047cbb7954792d1acdfb375939b65ede0af9f97055b31eef6f7
3
+ metadata.gz: 1886e30cb7c12fb80faac2bb6268651d19770843f332ad8daa8c0283d4654ecb
4
+ data.tar.gz: 344f2f3cb2dd39378f757440e812eb192d818352776a044e3e684835d54ef1a0
5
5
  SHA512:
6
- metadata.gz: f944327ad557443227149617a1ecc5fc79bd78a3715d96e1db986e71d782c7d1b110e28ff88023cbea0b86d6f6eb4e079ae062d4a95b3427b827b5cdf73b0e2a
7
- data.tar.gz: 3d96447eec1760afd73458b059d5659c58b6020edd38cd45295db1558463d6c6dc5b98484ccae61ace9b34c6d8cf5ed4c8c590d02670bc18d7566158c39ccec4
6
+ metadata.gz: ce3a6411127363f0635cc966dca7b04de9d5e504189c3bc1aa2a9d774ae7e12c66b2a771493c3260568b2673916af48633271f5fce44af3e53e74d3b2ba36381
7
+ data.tar.gz: cb8b39466ae50ddc3735101587c540e03d7369b89d7d36026dbf5f3888df78c7e655bc3f4c7abf9fa9f762041a595dd7930de72ae17f8be5414652972445eabe
@@ -6,7 +6,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- ## [0.1.0] - 2020-07-01
9
+ ## [0.1.3] - 2020-07-12
10
10
  ### Added
11
- - First Release with 2 included flight routes: Email and SMS. (plugged with Twilio and ActionMailer)
12
- - FlyJob included
11
+ - Fixed namespacing of the api endpoint
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support'
4
+
4
5
  require 'acts_as_living/version'
5
- require 'acts_as_living/class_methods'
6
+ require 'acts_as_living/acts_as_living'
7
+ require 'acts_as_living/methods_definer'
6
8
  require 'acts_as_living/enum_definer'
7
9
  require 'acts_as_living/callbacks_definer'
8
- require 'acts_as_living/instance_methods_definer'
9
10
  require 'acts_as_living/scopes_definer'
10
11
  require 'acts_as_living/validations_definer'
11
12
 
@@ -0,0 +1,25 @@
1
+
2
+ require 'active_support/concern'
3
+
4
+ module ActsAsLiving::ActsAsLiving
5
+ extend ActiveSupport::Concern
6
+
7
+ class_methods do
8
+ def acts_as_living(keys, phases: [], lock_on: [], death: :cancelled, spread: 1)
9
+ @stage_keys = keys
10
+ @phases = phases
11
+ @locked_stages = lock_on
12
+ @death = death
13
+ @spread = spread
14
+
15
+ run_definers
16
+ end
17
+
18
+ def run_definers
19
+ ActsAsLiving::MethodsDefiner.call(self)
20
+ ActsAsLiving::EnumDefiner.call(self)
21
+ ActsAsLiving::ScopesDefiner.call(self)
22
+ ActsAsLiving::ValidationsDefiner.call(self)
23
+ end
24
+ end
25
+ end
@@ -7,10 +7,10 @@
7
7
  # ->(_target, result) { result == false }
8
8
  # end
9
9
 
10
- # # defines before, after and around callbaks for each stage of the acts_as_living
10
+ # # defines before, after and around callbaks for each phase of the acts_as_living
11
11
  # # e.g. before_cancelled { do_something }
12
12
  # # e.g. after_activated :run_method
13
- # # e.g. after_status_change :run_method
13
+ # # e.g. after_stage_change :run_method
14
14
 
15
15
  # def self.call(klass)
16
16
  # klass.class_eval do
@@ -18,78 +18,78 @@
18
18
  # extend ClassMethods
19
19
  # include InstanceMethods
20
20
 
21
- # callbacks_for(:status_change)
22
- # callbacks_for(:life_stage_change)
23
- # status_keys.each(&method(:status_callbacks_for))
24
- # @life_stages.keys.each(&method(:lifestage_callbacks_for))
21
+ # callbacks_for(:stage_change)
22
+ # callbacks_for(:phase_change)
23
+ # stage_keys.each(&method(:stage_callbacks_for))
24
+ # @phases.keys.each(&method(:lifephase_callbacks_for))
25
25
  # end
26
26
  # end
27
27
 
28
28
  # module InstanceMethods
29
29
  # def save(*args)
30
- # return super(*args) unless valid? && status_changed? || valid? && new_record?
30
+ # return super(*args) unless valid? && stage_changed? || valid? && new_record?
31
31
 
32
- # _run_status_change_callbacks do
33
- # run_callbacks("status_change_to_#{status}") do
32
+ # _run_stage_change_callbacks do
33
+ # run_callbacks("stage_change_to_#{stage}") do
34
34
  # binding.pry if notice_of_termination_received?
35
- # life_stage_changed? ? run_life_stage_callbacks { binding.pry; 'hey'; super(*args) } : super(*args)
35
+ # phase_changed? ? run_phase_callbacks { binding.pry; 'hey'; super(*args) } : super(*args)
36
36
  # end
37
37
  # end
38
38
  # end
39
39
 
40
40
  # def save!(*args)
41
- # return super(*args) unless valid? && status_changed? || valid? && new_record?
41
+ # return super(*args) unless valid? && stage_changed? || valid? && new_record?
42
42
 
43
- # _run_status_change_callbacks do
44
- # run_callbacks("status_change_to_#{status}") do
45
- # life_stage_changed? ? run_life_stage_callbacks { binding.pry; 'hey'; super(*args) } : super(*args)
43
+ # _run_stage_change_callbacks do
44
+ # run_callbacks("stage_change_to_#{stage}") do
45
+ # phase_changed? ? run_phase_callbacks { binding.pry; 'hey'; super(*args) } : super(*args)
46
46
  # end
47
47
  # end
48
48
  # end
49
49
 
50
50
  # protected
51
51
 
52
- # def run_life_stage_callbacks(&block)
53
- # _run_life_stage_change_callbacks do
54
- # _run_life_stage_started_callbacks do
55
- # _run_life_stage_ended_callbacks(&block)
52
+ # def run_phase_callbacks(&block)
53
+ # _run_phase_change_callbacks do
54
+ # _run_phase_started_callbacks do
55
+ # _run_phase_ended_callbacks(&block)
56
56
  # end
57
57
  # end
58
58
  # end
59
59
 
60
- # def _run_life_stage_started_callbacks(&block)
61
- # life_stages_started.inject(block) do |blk, stage|
62
- # _run_stage_started_callbacks(stage, &blk)
60
+ # def _run_phase_started_callbacks(&block)
61
+ # phases_started.inject(block) do |blk, phase|
62
+ # _run_phase_started_callbacks(phase, &blk)
63
63
  # end
64
64
  # end
65
65
 
66
- # def _run_life_stage_ended_callbacks(&block)
67
- # life_stages_ended.inject(block) do |blk, stage|
68
- # _run_stage_ended_callbacks(stage, &blk)
66
+ # def _run_phase_ended_callbacks(&block)
67
+ # phases_ended.inject(block) do |blk, phase|
68
+ # _run_phase_ended_callbacks(phase, &blk)
69
69
  # end
70
70
  # end
71
71
 
72
- # def _run_stage_started_callbacks(stage, &block)
73
- # run_callbacks("#{stage}_started".to_sym, &block)
72
+ # def _run_phase_started_callbacks(phase, &block)
73
+ # run_callbacks("#{phase}_started".to_sym, &block)
74
74
  # end
75
75
 
76
- # def _run_stage_ended_callbacks(stage, &block)
77
- # run_callbacks("#{stage}_ended".to_sym, &block)
76
+ # def _run_phase_ended_callbacks(phase, &block)
77
+ # run_callbacks("#{phase}_ended".to_sym, &block)
78
78
  # end
79
79
  # end
80
80
 
81
81
  # module ClassMethods
82
- # def lifestage_callbacks_for(stage)
83
- # define_callback_methods_for("#{stage}_started".to_sym)
84
- # define_callback_methods_for("#{stage}_ended".to_sym)
82
+ # def lifephase_callbacks_for(phase)
83
+ # define_callback_methods_for("#{phase}_started".to_sym)
84
+ # define_callback_methods_for("#{phase}_ended".to_sym)
85
85
  # end
86
86
 
87
87
  # def callbacks_for(callback_name)
88
88
  # define_callback_methods_for(callback_name)
89
89
  # end
90
90
 
91
- # def status_callbacks_for(status_name)
92
- # define_callback_methods_for("status_change_to_#{status_name}")
91
+ # def stage_callbacks_for(stage_name)
92
+ # define_callback_methods_for("stage_change_to_#{stage_name}")
93
93
  # end
94
94
 
95
95
  # def _normalize_callback_options(options)
@@ -11,12 +11,12 @@ module ActsAsLiving::EnumDefiner
11
11
 
12
12
  module ClassMethods
13
13
  def enum_options
14
- statuses = @status_keys.map.with_index(&method(:to_enum_map)).to_h
15
- statuses.merge(@death => @spread * -1)
14
+ stages = @stage_keys.map.with_index(&method(:to_enum_map)).to_h
15
+ stages.merge(@death => @spread * -1)
16
16
  end
17
17
 
18
- def to_enum_map(status, index)
19
- [status, index * @spread]
18
+ def to_enum_map(stage, index)
19
+ [stage, index * @spread]
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActsAsLiving::MethodsDefiner
4
+ def self.call(klass)
5
+ klass.class_eval do
6
+ extend ClassMethods
7
+ include InstanceMethods
8
+
9
+ @stage_keys.each(&method(:define_stage_queries))
10
+ @phases.each(&method(:define_phase_queries))
11
+ end
12
+ end
13
+
14
+ module InstanceMethods
15
+ def stage_after(stage)
16
+ self.class.stage_after(stage)
17
+ end
18
+
19
+ def stages
20
+ self.class.stages
21
+ end
22
+
23
+ def stage_before(stage)
24
+ self.class.stage_before(stage)
25
+ end
26
+
27
+ def to_next_stage
28
+ update(stage: next_stage)
29
+ end
30
+
31
+ def to_next_stage!
32
+ update!(stage: next_stage)
33
+ end
34
+
35
+ def next_stage
36
+ stage_after(stage) if stage
37
+ end
38
+
39
+ def to_previous_stage
40
+ update(stage: previous_stage)
41
+ end
42
+
43
+ def to_previous_stage!
44
+ update!(stage: previous_stage)
45
+ end
46
+
47
+ def previous_stage
48
+ stage_before(stage)
49
+ end
50
+
51
+ def dying?
52
+ self.class.dying?(stage)
53
+ end
54
+
55
+ def newborn?
56
+ self.class.newborn?(stage)
57
+ end
58
+
59
+ def dead?
60
+ self.class.death == stage
61
+ end
62
+
63
+ def dead_or_dying?
64
+ dead? || dying?
65
+ end
66
+
67
+ def klass_phases_with_ranges
68
+ self.class.phases_with_ranges
69
+ end
70
+
71
+ def klass_phases_for(stage)
72
+ self.class.phases_for(stage)
73
+ end
74
+
75
+ def klass_stages
76
+ self.class.stages
77
+ end
78
+
79
+ def locked?(&block)
80
+ return unless block
81
+
82
+ @locked_on.to_set.intersect? [stage, stage_was].to_set
83
+ end
84
+
85
+ def phases
86
+ klass_phases_for(stage)
87
+ end
88
+
89
+ def phase_changed?
90
+ klass_phases_for(stage) != klass_phases_for(stage_was)
91
+ end
92
+
93
+ def phases_started
94
+ klass_phases_for(stage) - klass_phases_for(stage_was)
95
+ end
96
+
97
+ def phases_ended
98
+ klass_phases_for(stage_was) - klass_phases_for(stage)
99
+ end
100
+ end
101
+
102
+ module ClassMethods
103
+ def alive_stages
104
+ stages.except(@death).keys
105
+ end
106
+
107
+ def stage_keys
108
+ stages.keys
109
+ end
110
+
111
+ def stages_after(stage)
112
+ return [] if dying?(stage)
113
+
114
+ stages[stage_after(stage)..]
115
+ end
116
+
117
+ def stages_before(stage)
118
+ return [] if newborn?(stage)
119
+
120
+ index = stage_keys.find_index(stage)
121
+ stage_keys[0...index]
122
+ end
123
+
124
+ def stage_after(stage)
125
+ return if dying?(stage)
126
+
127
+ index = stage_keys.find_index(stage)
128
+ stage_keys[index + 1]
129
+ end
130
+
131
+ def stage_before(stage)
132
+ return if newborn?(stage)
133
+
134
+ index = stage_keys.find_index(stage)
135
+ stage_keys[index - 1]
136
+ end
137
+
138
+ def final_stage
139
+ stage_keys.last
140
+ end
141
+
142
+ def dying?(stage)
143
+ final_stage == stage
144
+ end
145
+
146
+ def newborn_stage
147
+ stages.key(0)
148
+ end
149
+
150
+ def death
151
+ @death
152
+ end
153
+
154
+ def newborn?(stage)
155
+ initial_stage == stage
156
+ end
157
+
158
+ def phases_with_ranges
159
+ @phases.map(&method(:to_phase_with_range)).to_h
160
+ end
161
+
162
+ def to_phase_with_range(phase, delimiter)
163
+ [phase, (stages[delimiter.first]..stages[delimiter.last])]
164
+ end
165
+
166
+ def phases
167
+ @phases
168
+ end
169
+
170
+ def phases_for(stage)
171
+ phases_with_ranges.keys.select do |phase|
172
+ phases_with_ranges[phase].include? stages[stage]
173
+ end
174
+ end
175
+
176
+ def define_phase_queries(phase, delimiters)
177
+ define_method("#{phase}?") do
178
+ if delimiters.length == 1
179
+ klass_stages[stage] == klass_stages[delimiters]
180
+ else
181
+ klass_stages[stage] >= klass_stages[delimiters.first] &&
182
+ klass_stages[stage] <= klass_stages[delimiters.second]
183
+ end
184
+ end
185
+
186
+ define_method("pre_#{phase}?") do
187
+ klass_stages[stage] < klass_stages[delimiters.first] unless cancelled?
188
+ end
189
+
190
+ define_method("past_#{phase}?") do
191
+ klass_stages[stage] > klass_stages[delimiters.last] || cancelled?
192
+ end
193
+ end
194
+
195
+ def define_stage_queries(stage_key)
196
+ define_method("stage_changed_to_#{stage_key}?") do
197
+ stage_changed? && stage_was == stage_key
198
+ end
199
+
200
+ define_method("stage_saved_to_#{stage_key}?") do
201
+ saved_change_to_stage? && stage == stage_key
202
+ end
203
+
204
+ define_method("pre_#{stage_key}?") do
205
+ klass_stages[stage] < klass_stages[stage_key] unless cancelled?
206
+ end
207
+
208
+ define_method("past_#{stage_key}?") do
209
+ klass_stages[stage] > klass_stages[stage_key] || cancelled?
210
+ end
211
+
212
+ define_method("cancelled_from_#{stage_key}?") do
213
+ stage == 'cancelled' && stage_was == stage_key
214
+ end
215
+ end
216
+ end
217
+ end
@@ -2,13 +2,18 @@
2
2
 
3
3
  require 'active_support'
4
4
  require 'rails/railtie'
5
+ require 'acts_as_living'
5
6
 
6
7
  module ActsAsLiving
7
8
  class Railtie < Rails::Railtie
8
9
  config.to_prepare do
9
10
  ActiveSupport.on_load(:active_record) do
10
- extend ActsAsLiving::ClassMethods
11
+ include ::ActsAsLiving::ActsAsLiving
11
12
  end
12
13
  end
14
+
15
+ rake_tasks do
16
+ load 'tasks/acts_as_living.rake'
17
+ end
13
18
  end
14
19
  end
@@ -1,20 +1,20 @@
1
1
  module ActsAsLiving::ScopesDefiner
2
2
  def self.call(klass)
3
3
  klass.class_eval do
4
- statuses.each do |status, _num|
5
- scope "past_#{status}", -> { where('status >= ?', statuses[status]) }
6
- scope "pre_#{status}", -> { where('status < ?', statuses[status]) }
7
- scope "not_#{status}", -> { where.not(status: status) }
4
+ stages.each do |stage, _num|
5
+ scope "past_#{stage}", -> { where('stage >= ?', stages[stage]) }
6
+ scope "pre_#{stage}", -> { where('stage < ?', stages[stage]) }
7
+ scope "not_#{stage}", -> { where.not(stage: stage) }
8
8
  end
9
9
 
10
- scope :cancelled, -> { where('status < 0') }
10
+ scope :cancelled, -> { where('stage < 0') }
11
11
 
12
- @life_stages.each do |stage, delimiters|
12
+ @phases.each do |phase, delimiters|
13
13
  if delimiters.length == 1
14
- scope stage, -> { where(status: delimiters.first) }
14
+ scope phase, -> { where(stage: delimiters.first) }
15
15
  else
16
- scope stage, lambda {
17
- where('status >= ? AND status <= ?', statuses[delimiters.first], statuses[delimiters.second])
16
+ scope phase, lambda {
17
+ where('stage >= ? AND stage <= ?', stages[delimiters.first], stages[delimiters.second])
18
18
  }
19
19
  end
20
20
  end
@@ -3,30 +3,30 @@ module ActsAsLiving::ValidationsDefiner
3
3
  klass.class_eval do
4
4
  include InstanceMethods
5
5
 
6
- validates :status, presence: true
6
+ validates :stage, presence: true
7
7
 
8
- validate :status_progression, on: :update, if: :status_changed?
9
- validate :initialized_status, on: :create, if: :status_changed?
8
+ validate :stage_progression, on: :update, if: :stage_changed?
9
+ validate :initialized_stage, on: :create, if: :stage_changed?
10
10
  end
11
11
  end
12
12
 
13
13
  module InstanceMethods
14
- def status_progression
15
- return if status.to_s == self.class.dead_status.to_s || status == status_after(status_was)
14
+ def stage_progression
15
+ return if stage.to_s == self.class.death.to_s || stage == stage_after(stage_was)
16
16
 
17
- message = if status_was == self.class.final_status
18
- "The contract can only be updated to '#{self.class.dead_status}'"
17
+ message = if stage_was == self.class.final_stage
18
+ "The contract can only be updated to '#{self.class.death}'"
19
19
  else
20
- "The contract can only be updated to '#{self.class.dead_status}' or '#{status_after(status_was)}'"
20
+ "The contract can only be updated to '#{self.class.death}' or '#{stage_after(stage_was)}'"
21
21
  end
22
22
 
23
- errors.add(:status, message)
23
+ errors.add(:stage, message)
24
24
  end
25
25
 
26
- def initialized_status
27
- return if status == self.class.initial_status
26
+ def initialized_stage
27
+ return if stage == self.class.initial_stage
28
28
 
29
- errors.add(:status, "Contract has to be initialized with '#{self.class.initial_status}' status")
29
+ errors.add(:stage, "Contract has to be initialized with '#{self.class.initial_stage}' stage")
30
30
  end
31
31
  end
32
32
  end
@@ -1,3 +1,3 @@
1
1
  module ActsAsLiving
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -0,0 +1,18 @@
1
+ namespace :acts_as_living do
2
+ desc 'Install'
3
+ task install_migration: :environment do
4
+ options = {}
5
+ OptionParser.new do |opts|
6
+ opts.banner = 'Usage: rake add [options]'
7
+ opts.on('-m', '--model ARG', String) { |model| options[:model] = model }
8
+ opts.on('-s', '--stages ARG', Array) { |stages| options[:stages] = stages }
9
+ end.parse!
10
+
11
+ migration_name = "add_life_stages_to_#{options[:model]}"
12
+ timestamps_code = stages.map { |stage| "#{stage}_at:datetime" }.join(' ')
13
+ stages_code = 'stage:integer past_stages:string{array: true, default: []}'
14
+
15
+ system "rails g migration #{migration_name} #{stages_code} #{timestamps_code}"
16
+ end
17
+ end
18
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_living
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guilherme Andrade
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-01 00:00:00.000000000 Z
11
+ date: 2020-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -70,7 +70,7 @@ dependencies:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: 6.0.3
73
- description: An ActiveRecord plugin that assists in acts_as_living status progressions.
73
+ description: An ActiveRecord plugin that assists in acts_as_living stage progressions.
74
74
  email:
75
75
  - guilherme.andrade.ao@gmail.com
76
76
  executables: []
@@ -80,14 +80,15 @@ files:
80
80
  - Changelog.md
81
81
  - README.md
82
82
  - lib/acts_as_living.rb
83
+ - lib/acts_as_living/acts_as_living.rb
83
84
  - lib/acts_as_living/callbacks_definer.rb
84
- - lib/acts_as_living/class_methods.rb
85
85
  - lib/acts_as_living/enum_definer.rb
86
- - lib/acts_as_living/instance_methods_definer.rb
86
+ - lib/acts_as_living/methods_definer.rb
87
87
  - lib/acts_as_living/railtie.rb
88
88
  - lib/acts_as_living/scopes_definer.rb
89
89
  - lib/acts_as_living/validations_definer.rb
90
90
  - lib/acts_as_living/version.rb
91
+ - lib/tasks/acts_as_living.rake
91
92
  homepage: https://github.com/guilherme-andrade/acts_as_living
92
93
  licenses:
93
94
  - MIT
@@ -103,7 +104,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
104
  requirements:
104
105
  - - ">="
105
106
  - !ruby/object:Gem::Version
106
- version: '0'
107
+ version: 2.5.0
107
108
  required_rubygems_version: !ruby/object:Gem::Requirement
108
109
  requirements:
109
110
  - - ">="
@@ -113,5 +114,5 @@ requirements: []
113
114
  rubygems_version: 3.0.3
114
115
  signing_key:
115
116
  specification_version: 4
116
- summary: An ActiveRecord plugin that assists in acts_as_living status progressions.
117
+ summary: An ActiveRecord plugin that assists in acts_as_living stage progressions.
117
118
  test_files: []
@@ -1,97 +0,0 @@
1
-
2
- module ActsAsLiving::ClassMethods
3
- # validates :status, presence: true
4
-
5
- def acts_as_living(keys, **options)
6
- @status_keys = keys
7
- @life_stages = options.dig(:life_stages)
8
- @locked_statuses = options.dig(:lock_on)
9
- @death = options.dig(:death)
10
- @spread = options.dig(:spread)
11
- @column = options.dig(:column)
12
-
13
- ActsAsLiving::EnumDefiner.call(self)
14
-
15
- run_definers
16
- end
17
-
18
- def run_definers
19
- ActsAsLiving::ScopesDefiner.call(self)
20
- ActsAsLiving::InstanceMethodsDefiner.call(self)
21
- # ActsAsLiving::CallbacksDefiner.call(self)
22
- ActsAsLiving::ValidationsDefiner.call(self)
23
- end
24
-
25
- def alive_statuses
26
- statuses.except(@death).keys
27
- end
28
-
29
- def status_keys
30
- statuses.keys
31
- end
32
-
33
- def statuses_after(status)
34
- return [] if final_status?(status)
35
-
36
- statuses[status_after(status)..]
37
- end
38
-
39
- def statuses_before(status)
40
- return [] if initial_status?(status)
41
-
42
- index = status_keys.find_index(status)
43
- status_keys[0...index]
44
- end
45
-
46
- def status_after(status)
47
- return if final_status?(status)
48
-
49
- index = status_keys.find_index(status)
50
- status_keys[index + 1]
51
- end
52
-
53
- def status_before(status)
54
- return if initial_status?(status)
55
-
56
- index = status_keys.find_index(status)
57
- status_keys[index - 1]
58
- end
59
-
60
- def final_status
61
- status_keys.last
62
- end
63
-
64
- def final_status?(status)
65
- final_status == status
66
- end
67
-
68
- def initial_status
69
- statuses.key(0)
70
- end
71
-
72
- def dead_status
73
- @death
74
- end
75
-
76
- def initial_status?(status)
77
- initial_status == status
78
- end
79
-
80
- def stages_with_ranges
81
- @life_stages.map(&method(:to_stage_with_range)).to_h
82
- end
83
-
84
- def to_stage_with_range(stage, delimiter)
85
- [stage, (statuses[delimiter.first]..statuses[delimiter.last])]
86
- end
87
-
88
- def life_stages
89
- @life_stages
90
- end
91
-
92
- def life_stages_for(status)
93
- stages_with_ranges.keys.select do |stage|
94
- stages_with_ranges[stage].include? statuses[status]
95
- end
96
- end
97
- end
@@ -1,141 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActsAsLiving::InstanceMethodsDefiner
4
- def self.call(klass)
5
- klass.class_eval do
6
- extend ClassMethods
7
- include InstanceMethods
8
-
9
- @life_stages.each(&method(:define_stage_queries))
10
-
11
- @status_keys.each(&method(:define_changed_queries))
12
- end
13
- end
14
-
15
- module InstanceMethods
16
- def status_after(status)
17
- self.class.status_after(status)
18
- end
19
-
20
- def statuses
21
- self.class.statuses
22
- end
23
-
24
- def status_before(status)
25
- self.class.status_before(status)
26
- end
27
-
28
- def to_next_status
29
- update(status: next_status)
30
- end
31
-
32
- def to_next_status!
33
- update!(status: next_status)
34
- end
35
-
36
- def next_status
37
- status_after(status) if status
38
- end
39
-
40
- def to_previous_status
41
- update(status: previous_status)
42
- end
43
-
44
- def to_previous_status!
45
- update!(status: previous_status)
46
- end
47
-
48
- def previous_status
49
- status_before(status)
50
- end
51
-
52
- def final_status?
53
- self.class.final_status?(status)
54
- end
55
-
56
- def initial_status?
57
- self.class.initial_status?(status)
58
- end
59
-
60
- def dead_status?
61
- self.class.dead_status == status
62
- end
63
-
64
- def dead_or_finalized?
65
- dead_status? || final_status?
66
- end
67
-
68
- def klass_stages_with_ranges
69
- self.class.stages_with_ranges
70
- end
71
-
72
- def klass_life_stages_for(status)
73
- self.class.life_stages_for(status)
74
- end
75
-
76
- def klass_statuses
77
- self.class.statuses
78
- end
79
-
80
- def locked?(&block)
81
- return unless block
82
-
83
- @locked_on.to_set.intersect? [status, status_was].to_set
84
- end
85
-
86
- def life_stages
87
- klass_life_stages_for(status)
88
- end
89
-
90
- def life_stage_changed?
91
- klass_life_stages_for(status) != klass_life_stages_for(status_was)
92
- end
93
-
94
- def life_stages_started
95
- klass_life_stages_for(status) - klass_life_stages_for(status_was)
96
- end
97
-
98
- def life_stages_ended
99
- klass_life_stages_for(status_was) - klass_life_stages_for(status)
100
- end
101
- end
102
-
103
- module ClassMethods
104
- def define_stage_queries(stage, delimiters)
105
- define_method("#{stage}?") do
106
- if delimiters.length == 1
107
- klass_statuses[status] == klass_statuses[delimiters]
108
- else
109
- klass_statuses[status] >= klass_statuses[delimiters.first] &&
110
- klass_statuses[status] <= klass_statuses[delimiters.second]
111
- end
112
- end
113
-
114
- define_method("pre_#{stage}?") do
115
- klass_statuses[status] < klass_statuses[delimiters.first] unless cancelled?
116
- end
117
-
118
- define_method("past_#{stage}?") do
119
- klass_statuses[status] > klass_statuses[delimiters.last] || cancelled?
120
- end
121
- end
122
-
123
- def define_changed_queries(status_key)
124
- define_method("status_changed_to_#{status_key}?") do
125
- status_changed? && status_was == status_key
126
- end
127
-
128
- define_method("pre_#{status_key}?") do
129
- klass_statuses[status] < klass_statuses[status_key] unless cancelled?
130
- end
131
-
132
- define_method("past_#{status_key}?") do
133
- klass_statuses[status] > klass_statuses[status_key] || cancelled?
134
- end
135
-
136
- define_method("cancelled_from_#{status_key}?") do
137
- status == 'cancelled' && status_was == status_key
138
- end
139
- end
140
- end
141
- end