acts_as_living 0.1.0 → 0.1.6

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