progressive 0.0.2 → 0.0.3

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
  SHA1:
3
- metadata.gz: 965939ad3863d6a0c31c7d6531e4dcd5304f25ca
4
- data.tar.gz: c00604acf1b260e35675ee60910a7c34e7c7847c
3
+ metadata.gz: 64289288aa2a2161424c2f7e917358fb6ecbd49e
4
+ data.tar.gz: ad002250254baacb97690247cd5ee6fc89348e0a
5
5
  SHA512:
6
- metadata.gz: 0ef9acd62d8ca2c14313fd128d4c4c101d34a9e078563848fdac1cdc28d12f165dda937046c1b94823a7c399ad2e8d90dd02219dc10fbdc8f518e3df15e4d86f
7
- data.tar.gz: ad5c52c3fa5e2fd20b3f449ead496beba076cd0110c8577c05af5fb6a96463706be776a37f7d32bd238ba356a3e86774f1bbca89ec69b29f0f5f116bc2bba623
6
+ metadata.gz: a2dcc8a2730c54a7af80ecb691b7a3a5bff4fbf0c38c51545ee9af1f49e1c4b67c0236972462dd95b39bfe0daa9db0880aeb4176e586e8f83b7d6b14a83eb6d4
7
+ data.tar.gz: f23dd3192472187b93046ee3191d2ae94fff61160d0770feaa399f8305860e41e8bcc43c04aef7b749406ca146ec7c064d4a491acedac61e56d6627284c765e0
@@ -4,7 +4,7 @@ module Progressive
4
4
  attr_reader :events
5
5
 
6
6
  def initialize(&block)
7
- @events = {}
7
+ @events = ActiveSupport::HashWithIndifferentAccess.new
8
8
  return unless block.present?
9
9
  instance_eval(&block)
10
10
  end
@@ -25,7 +25,7 @@ module Progressive
25
25
  #
26
26
  # Returns true if event exists, false if not.
27
27
  def event?(state)
28
- @events.key?(state.to_sym)
28
+ @events.key?(state)
29
29
  end
30
30
  end
31
31
 
@@ -54,7 +54,7 @@ module Progressive
54
54
  raise MissingConfiguration if block.nil?
55
55
 
56
56
  @options = options
57
- @states = {}
57
+ @states = ActiveSupport::HashWithIndifferentAccess.new
58
58
 
59
59
  instance_eval(&block)
60
60
  end
@@ -65,7 +65,7 @@ module Progressive
65
65
  #
66
66
  # Returns true if exists, false if not.
67
67
  def event?(event)
68
- event_names.include?(event.to_sym)
68
+ event_names.include?(event.to_s)
69
69
  end
70
70
 
71
71
  # Public: All possible events that can be applied to the subject. Doesn't
@@ -95,7 +95,7 @@ module Progressive
95
95
  #
96
96
  # Returns true if defined, false if not.
97
97
  def state?(state)
98
- @states.key?(state.to_sym)
98
+ @states.key?(state)
99
99
  end
100
100
 
101
101
  # Public: Returns the default state for the specification.
@@ -104,7 +104,7 @@ module Progressive
104
104
  def default_state
105
105
  @default_state ||=
106
106
  if options.key?(:default)
107
- options[:default]
107
+ options[:default].to_s
108
108
  elsif states.any?
109
109
  states.keys.first
110
110
  end
@@ -1,39 +1,72 @@
1
1
  module Progressive
2
2
  class State < ActiveRecord::Base
3
3
  belongs_to :subject, polymorphic: true
4
-
5
- validates :subject_type, presence: true
6
- validates :subject_id, presence: true, uniqueness: { scope: [:subject_type] }
7
4
  validates :state, presence: true
8
5
 
6
+ after_initialize :set_default_state, :if => :specification?
7
+ before_validation :set_default_state, :on => :create
8
+
9
9
  def specification
10
- @specification ||= subject.specification
10
+ Progressive.specifications[subject_type]
11
+ end
12
+
13
+ def specification?
14
+ return false unless loaded?
15
+ specification.present?
16
+ end
17
+
18
+ # If we try to access subject_type before it's present, method_missing goes
19
+ # nuts.
20
+ #
21
+ # Returns true if loaded, false if not.
22
+ def loaded?
23
+ !read_attribute(:subject_type).nil?
11
24
  end
12
25
 
13
26
  def method_missing(method_sym, *args, &block)
14
- if specification.state?(method_sym)
27
+ return super unless loaded?
28
+
29
+ if specification.event?(method_sym)
15
30
  to(method_sym, *args)
16
- elsif method_sym.to_s[-1] == '?'
31
+ elsif method_sym.to_s[-1] == '?' && specification.state?(method_sym.to_s[0..-2])
17
32
  predicate = method_sym.to_s[0..-2]
18
- state == predicate
33
+ state.to_sym == predicate.to_sym
19
34
  else
20
35
  super
21
36
  end
22
37
  end
23
38
 
39
+ # This will be available for all callbacks to get better context around event
40
+ # changes.
41
+ #
42
+ # Returns Hash.
43
+ def default_event_context
44
+ {}
45
+ end
46
+
24
47
  # Public: Transition from the current state to a new state.
25
48
  #
26
49
  # state - The event
27
50
  #
28
51
  # Returns nothing.
29
- def to(state, options = {})
30
- return false unless current_state.event?(state)
52
+ def to(event, options = {})
53
+ return false unless current_state.event?(event)
54
+
55
+ current_event = current_state.events[event]
56
+
57
+ previous_event_context = subject.event_context
58
+ subject.event_context = default_event_context.merge(options).merge({
59
+ from: state.to_sym,
60
+ to: current_event.to
61
+ })
31
62
 
32
63
  subject.run_callbacks(:progress) do
33
- subject.run_callbacks(state) do
34
- update_attribute(:state, state)
64
+ subject.run_callbacks(current_event.name) do
65
+ update_attribute(:state, current_event.to)
35
66
  end
36
67
  end
68
+ ensure
69
+ subject.event_context = previous_event_context
37
70
  end
38
71
 
39
72
  def current_state
@@ -43,6 +76,16 @@ module Progressive
43
76
  def to_s
44
77
  state
45
78
  end
46
- delegate :humanize, to: :to_s
79
+
80
+ def to_param
81
+ state
82
+ end
83
+
84
+ private
85
+
86
+ def set_default_state
87
+ return unless specification?
88
+ self.state ||= specification.default_state
89
+ end
47
90
  end
48
91
  end
@@ -7,9 +7,9 @@ module Progressive
7
7
  include ActiveModel::Callbacks
8
8
 
9
9
  included do
10
- class_attribute :specification
11
-
12
10
  define_model_callbacks :progress, only: [:before, :after]
11
+
12
+ attr_accessor :event_context
13
13
  end
14
14
 
15
15
  module ClassMethods
@@ -25,22 +25,18 @@ module Progressive
25
25
  self.specification = Specification.new(options, &block)
26
26
  define_model_callbacks(*specification.event_names, only: [:before, :after])
27
27
  end
28
- end
29
28
 
30
- def method_missing(method_sym, *args, &block)
31
- if method_sym.to_s[-1] == '?' && specification.state?(method_sym.to_s[0..-2])
32
- specification.send(method_sym)
33
- else
34
- super
29
+ def specification=(specification)
30
+ Progressive.specifications[name] = specification
31
+ end
32
+
33
+ def specification
34
+ Progressive.specifications[name]
35
35
  end
36
36
  end
37
37
 
38
38
  def specification
39
39
  self.class.specification
40
40
  end
41
-
42
- def human_state
43
- state.humanize
44
- end
45
41
  end
46
42
  end
@@ -1,3 +1,3 @@
1
1
  module Progressive
2
- VERSION = '0.0.2'.freeze
2
+ VERSION = '0.0.3'.freeze
3
3
  end
data/lib/progressive.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  require 'progressive/version'
2
2
 
3
3
  module Progressive
4
- # Your code goes here...
4
+ class InvalidProgress < StandardError; end
5
+ class MissingConfiguration < StandardError; end
6
+
7
+ # Direct mapping of service names to their service object.
8
+ mattr_accessor :specifications
9
+ @@specifications = {}
5
10
  end
6
11
 
7
12
  require 'progressive/specification'
data/progressive.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'activemodel', '>= 3.0.0'
21
+ spec.add_dependency 'activemodel', '>= 5.0.0'
22
22
  spec.add_development_dependency 'bundler', '~> 1.3'
23
23
  spec.add_development_dependency 'rake'
24
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: progressive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - dewski
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0
19
+ version: 5.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.0.0
26
+ version: 5.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement