rails_state_machine 2.1.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.7.0.pg.lock CHANGED
@@ -1,75 +1,80 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_state_machine (2.1.1)
4
+ rails_state_machine (3.0.0)
5
5
  activerecord
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- actioncable (7.0.0)
11
- actionpack (= 7.0.0)
12
- activesupport (= 7.0.0)
10
+ actioncable (7.0.1)
11
+ actionpack (= 7.0.1)
12
+ activesupport (= 7.0.1)
13
13
  nio4r (~> 2.0)
14
14
  websocket-driver (>= 0.6.1)
15
- actionmailbox (7.0.0)
16
- actionpack (= 7.0.0)
17
- activejob (= 7.0.0)
18
- activerecord (= 7.0.0)
19
- activestorage (= 7.0.0)
20
- activesupport (= 7.0.0)
15
+ actionmailbox (7.0.1)
16
+ actionpack (= 7.0.1)
17
+ activejob (= 7.0.1)
18
+ activerecord (= 7.0.1)
19
+ activestorage (= 7.0.1)
20
+ activesupport (= 7.0.1)
21
21
  mail (>= 2.7.1)
22
- actionmailer (7.0.0)
23
- actionpack (= 7.0.0)
24
- actionview (= 7.0.0)
25
- activejob (= 7.0.0)
26
- activesupport (= 7.0.0)
22
+ net-imap
23
+ net-pop
24
+ net-smtp
25
+ actionmailer (7.0.1)
26
+ actionpack (= 7.0.1)
27
+ actionview (= 7.0.1)
28
+ activejob (= 7.0.1)
29
+ activesupport (= 7.0.1)
27
30
  mail (~> 2.5, >= 2.5.4)
31
+ net-imap
32
+ net-pop
33
+ net-smtp
28
34
  rails-dom-testing (~> 2.0)
29
- actionpack (7.0.0)
30
- actionview (= 7.0.0)
31
- activesupport (= 7.0.0)
35
+ actionpack (7.0.1)
36
+ actionview (= 7.0.1)
37
+ activesupport (= 7.0.1)
32
38
  rack (~> 2.0, >= 2.2.0)
33
39
  rack-test (>= 0.6.3)
34
40
  rails-dom-testing (~> 2.0)
35
41
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
36
- actiontext (7.0.0)
37
- actionpack (= 7.0.0)
38
- activerecord (= 7.0.0)
39
- activestorage (= 7.0.0)
40
- activesupport (= 7.0.0)
42
+ actiontext (7.0.1)
43
+ actionpack (= 7.0.1)
44
+ activerecord (= 7.0.1)
45
+ activestorage (= 7.0.1)
46
+ activesupport (= 7.0.1)
41
47
  globalid (>= 0.6.0)
42
48
  nokogiri (>= 1.8.5)
43
- actionview (7.0.0)
44
- activesupport (= 7.0.0)
49
+ actionview (7.0.1)
50
+ activesupport (= 7.0.1)
45
51
  builder (~> 3.1)
46
52
  erubi (~> 1.4)
47
53
  rails-dom-testing (~> 2.0)
48
54
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
49
- activejob (7.0.0)
50
- activesupport (= 7.0.0)
55
+ activejob (7.0.1)
56
+ activesupport (= 7.0.1)
51
57
  globalid (>= 0.3.6)
52
- activemodel (7.0.0)
53
- activesupport (= 7.0.0)
54
- activerecord (7.0.0)
55
- activemodel (= 7.0.0)
56
- activesupport (= 7.0.0)
57
- activestorage (7.0.0)
58
- actionpack (= 7.0.0)
59
- activejob (= 7.0.0)
60
- activerecord (= 7.0.0)
61
- activesupport (= 7.0.0)
58
+ activemodel (7.0.1)
59
+ activesupport (= 7.0.1)
60
+ activerecord (7.0.1)
61
+ activemodel (= 7.0.1)
62
+ activesupport (= 7.0.1)
63
+ activestorage (7.0.1)
64
+ actionpack (= 7.0.1)
65
+ activejob (= 7.0.1)
66
+ activerecord (= 7.0.1)
67
+ activesupport (= 7.0.1)
62
68
  marcel (~> 1.0)
63
69
  mini_mime (>= 1.1.0)
64
- activesupport (7.0.0)
70
+ activesupport (7.0.1)
65
71
  concurrent-ruby (~> 1.0, >= 1.0.2)
66
72
  i18n (>= 1.6, < 2)
67
73
  minitest (>= 5.1)
68
74
  tzinfo (~> 2.0)
69
75
  builder (3.2.4)
70
- byebug (11.1.3)
71
76
  coderay (1.1.3)
72
- concurrent-ruby (1.1.9)
77
+ concurrent-ruby (1.2.2)
73
78
  crass (1.0.6)
74
79
  database_cleaner (2.0.1)
75
80
  database_cleaner-active_record (~> 2.0.0)
@@ -77,58 +82,74 @@ GEM
77
82
  activerecord (>= 5.a)
78
83
  database_cleaner-core (~> 2.0.0)
79
84
  database_cleaner-core (2.0.1)
85
+ date (3.3.4)
80
86
  diff-lcs (1.4.4)
81
- erubi (1.10.0)
82
- gemika (0.6.1)
83
- globalid (1.0.0)
84
- activesupport (>= 5.0)
85
- i18n (1.8.11)
87
+ erubi (1.12.0)
88
+ gemika (0.8.2)
89
+ globalid (1.2.1)
90
+ activesupport (>= 6.1)
91
+ i18n (1.14.1)
86
92
  concurrent-ruby (~> 1.0)
87
- loofah (2.13.0)
93
+ loofah (2.22.0)
88
94
  crass (~> 1.0.2)
89
- nokogiri (>= 1.5.9)
90
- mail (2.7.1)
95
+ nokogiri (>= 1.12.0)
96
+ mail (2.8.1)
91
97
  mini_mime (>= 0.1.1)
98
+ net-imap
99
+ net-pop
100
+ net-smtp
92
101
  marcel (1.0.2)
93
102
  method_source (1.0.0)
94
- mini_mime (1.1.2)
95
- minitest (5.15.0)
96
- nio4r (2.5.8)
97
- nokogiri (1.12.5-x86_64-linux)
103
+ mini_mime (1.1.5)
104
+ mini_portile2 (2.8.5)
105
+ minitest (5.20.0)
106
+ net-imap (0.3.7)
107
+ date
108
+ net-protocol
109
+ net-pop (0.1.2)
110
+ net-protocol
111
+ net-protocol (0.2.2)
112
+ timeout
113
+ net-smtp (0.4.0)
114
+ net-protocol
115
+ nio4r (2.7.0)
116
+ nokogiri (1.15.5)
117
+ mini_portile2 (~> 2.8.2)
98
118
  racc (~> 1.4)
99
- pg (1.2.3)
100
- pry (0.13.1)
119
+ nokogiri (1.15.5-x86_64-linux)
120
+ racc (~> 1.4)
121
+ pg (1.5.4)
122
+ pry (0.14.2)
101
123
  coderay (~> 1.1)
102
124
  method_source (~> 1.0)
103
- pry-byebug (3.9.0)
104
- byebug (~> 11.0)
105
- pry (~> 0.13.0)
106
- racc (1.6.0)
107
- rack (2.2.3)
108
- rack-test (1.1.0)
109
- rack (>= 1.0, < 3)
110
- rails (7.0.0)
111
- actioncable (= 7.0.0)
112
- actionmailbox (= 7.0.0)
113
- actionmailer (= 7.0.0)
114
- actionpack (= 7.0.0)
115
- actiontext (= 7.0.0)
116
- actionview (= 7.0.0)
117
- activejob (= 7.0.0)
118
- activemodel (= 7.0.0)
119
- activerecord (= 7.0.0)
120
- activestorage (= 7.0.0)
121
- activesupport (= 7.0.0)
125
+ racc (1.7.3)
126
+ rack (2.2.8)
127
+ rack-test (2.1.0)
128
+ rack (>= 1.3)
129
+ rails (7.0.1)
130
+ actioncable (= 7.0.1)
131
+ actionmailbox (= 7.0.1)
132
+ actionmailer (= 7.0.1)
133
+ actionpack (= 7.0.1)
134
+ actiontext (= 7.0.1)
135
+ actionview (= 7.0.1)
136
+ activejob (= 7.0.1)
137
+ activemodel (= 7.0.1)
138
+ activerecord (= 7.0.1)
139
+ activestorage (= 7.0.1)
140
+ activesupport (= 7.0.1)
122
141
  bundler (>= 1.15.0)
123
- railties (= 7.0.0)
124
- rails-dom-testing (2.0.3)
125
- activesupport (>= 4.2.0)
142
+ railties (= 7.0.1)
143
+ rails-dom-testing (2.2.0)
144
+ activesupport (>= 5.0.0)
145
+ minitest
126
146
  nokogiri (>= 1.6)
127
- rails-html-sanitizer (1.4.2)
128
- loofah (~> 2.3)
129
- railties (7.0.0)
130
- actionpack (= 7.0.0)
131
- activesupport (= 7.0.0)
147
+ rails-html-sanitizer (1.6.0)
148
+ loofah (~> 2.21)
149
+ nokogiri (~> 1.14)
150
+ railties (7.0.1)
151
+ actionpack (= 7.0.1)
152
+ activesupport (= 7.0.1)
132
153
  method_source
133
154
  rake (>= 12.2)
134
155
  thor (~> 1.0)
@@ -147,25 +168,28 @@ GEM
147
168
  diff-lcs (>= 1.2.0, < 2.0)
148
169
  rspec-support (~> 3.10.0)
149
170
  rspec-support (3.10.3)
150
- thor (1.1.0)
151
- tzinfo (2.0.4)
171
+ thor (1.3.0)
172
+ timeout (0.4.1)
173
+ tzinfo (2.0.6)
152
174
  concurrent-ruby (~> 1.0)
153
- websocket-driver (0.7.5)
175
+ websocket-driver (0.7.6)
154
176
  websocket-extensions (>= 0.1.0)
155
177
  websocket-extensions (0.1.5)
156
- zeitwerk (2.5.1)
178
+ zeitwerk (2.6.12)
157
179
 
158
180
  PLATFORMS
181
+ ruby
159
182
  x86_64-linux
160
183
 
161
184
  DEPENDENCIES
185
+ activerecord (= 7.0.1)
162
186
  database_cleaner
163
- gemika
164
- pg
165
- pry-byebug
166
- rails (~> 7.0.0)
187
+ gemika (>= 0.8.1)
188
+ pg (> 1.2.3)
189
+ pry
190
+ rails (= 7.0.1)
167
191
  rails_state_machine!
168
- rake
192
+ rake (> 10.0)
169
193
  rspec (~> 3.5)
170
194
 
171
195
  BUNDLED WITH
data/Gemfile.lock CHANGED
@@ -1 +1 @@
1
- Gemfile.5.1.pg.lock
1
+ Gemfile.7.0.pg.lock
data/README.md CHANGED
@@ -56,8 +56,8 @@ A model instance offers these state machine methods:
56
56
  - `<event_name>` call an event and transition into a new state. The record will be `save`d, if valid.
57
57
  - `<event_name>!` call an event and transition into a new state. Calls `save!` to save the record.
58
58
  - `may_<event_name>?` to find out if an event transition could be taken. Note that this will not validate if the model is valid afterwards.
59
- - `state_event=` to take a state event, but not save yet. Commonly used for forms where the controller takes a "state_event" param and saves.
60
- - `state_event` to get the name of the event that will be called
59
+ - `<state_name>_event=` to set the event the record tries to call on save. If the event is invalid, an `:invalid` error on the `<state_name>_event` is set. Commonly used for forms where the controller takes a "<state_name>_event" param and saves.
60
+ - `<state_name>_event` to get the name of the event that will be called
61
61
 
62
62
  Should you ever need to query the state machine for its states or events, it is accessible via `state_machine` class or instance methods on the model. See [`state_machine.rb`](https://github.com/makandra/rails_state_machine/blob/master/lib/rails_state_machine/state_machine.rb) for a list of available methods. This is mostly helpful in tests.
63
63
 
@@ -107,7 +107,7 @@ end
107
107
 
108
108
  To use a state attribute other than the default `state`, pass it to the `.state_machine` method:
109
109
 
110
- ```
110
+ ```ruby
111
111
  state_machine :review_state do
112
112
  # ...
113
113
  end
@@ -116,13 +116,29 @@ end
116
116
  This also allows you to define multiple state machines on the same model. Note that event
117
117
  and state names still have to be unique for the whole model.
118
118
 
119
+ If you define multiple state machines on the same model, and use state names more than once,
120
+ you must use a prefix to avoid name collisions.
121
+
122
+ A prefix may be specified by passing the `:prefix` option when declaring your state machine:
123
+
124
+ ```ruby
125
+ state_machine :review_state, prefix: 'some_prefix' do
126
+ # ...
127
+ end
128
+ ```
129
+
130
+ Note: The `prefix` option is designed to apply only to constants and state methods **defined by the gem**.
131
+
132
+ **State event names** are manually defined by the developer and thus not altered even if the `prefix`
133
+ option is used. It's advised to review them regarding potential naming collision and clarity when
134
+ introducing the `prefix` method.
119
135
 
120
136
  ## Taking multiple transitions
121
137
 
122
138
  You can safely take a second transition inside an after_save callback. All relevant
123
139
  callbacks will be run.
124
140
 
125
- ```
141
+ ```ruby
126
142
  state_machine do
127
143
  state :draft, initial: true
128
144
  state :review_pending
data/bin/console CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'bundler/setup'
4
4
  require 'rails_state_machine'
5
- require 'pry-byebug'
5
+ require 'pry'
6
6
 
7
7
  # You can add fixtures and/or initialization code here to make experimenting
8
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,6 +10,7 @@ module RailsStateMachine
10
10
 
11
11
  def register_callbacks(model)
12
12
  model.class_eval do
13
+ before_validation :set_state_from_state_event, prepend: true
13
14
  before_validation :run_state_events_before_validation
14
15
  before_save :register_state_events_for_callbacks
15
16
  before_save { flush_state_event_callbacks(:before_save) }
@@ -25,6 +26,16 @@ module RailsStateMachine
25
26
  end
26
27
  end
27
28
 
29
+ def set_state_from_state_event
30
+ state_machine_state_managers.each do |state_manager|
31
+ next if state_manager.state_event.blank?
32
+
33
+ unless state_manager.transition_to(state_manager.state_event)
34
+ errors.add(:"#{state_manager.state_attribute}_event", :invalid)
35
+ end
36
+ end
37
+ end
38
+
28
39
  def run_state_events_before_validation
29
40
  # Since validations may be skipped, we will not register validation callbacks in @state_event_callbacks,
30
41
  # but call them explicitly when before_validation callbacks are triggered.
@@ -7,15 +7,15 @@ module RailsStateMachine
7
7
  extend ClassMethods
8
8
 
9
9
  cattr_accessor :state_machines
10
- self.state_machines = {}
10
+ self.state_machines ||= {}
11
11
 
12
12
  delegate :state_machine, to: :class
13
13
  end
14
14
  end
15
15
 
16
16
  module ClassMethods
17
- def state_machine(state_attribute = DEFAULT_STATE_ATTRIBUTE, &block)
18
- state_machine = state_machines[state_attribute] ||= StateMachine.new(self, state_attribute)
17
+ def state_machine(state_attribute = DEFAULT_STATE_ATTRIBUTE, prefix: '', &block)
18
+ state_machine = state_machines[state_attribute] ||= StateMachine.new(self, state_attribute, prefix: prefix)
19
19
  if block
20
20
  include(Callbacks) unless self < Callbacks
21
21
  state_machine.configure(&block)
@@ -1,24 +1,32 @@
1
1
  module RailsStateMachine
2
2
  class StateMachine
3
- attr_reader :model
4
3
 
5
- def initialize(model, state_attribute)
4
+ StateAlreadyDefinedError = Class.new(StandardError)
5
+
6
+ def initialize(model, state_attribute, prefix: '')
6
7
  @model = model
7
8
  @state_attribute = state_attribute
9
+ @prefix = prefix
10
+ @prefix_for_constant_definition = "#{@prefix.upcase}_" if @prefix.present?
11
+ @prefix_for_method_definition = "#{@prefix.downcase}_" if @prefix.present?
8
12
  @states_by_name = {}
9
13
  @events_by_name = {}
10
14
  build_model_module
11
15
  end
12
16
 
17
+ attr_reader :model, :prefix, :prefix_for_constant_definition, :prefix_for_method_definition, :state_attribute
18
+
13
19
  def configure(&block)
14
20
  instance_eval(&block)
15
21
 
22
+ check_if_states_already_defined
23
+
16
24
  define_state_methods
17
25
  define_state_constants
18
26
  register_initial_state
19
27
 
20
28
  define_event_methods
21
- define_model_methods
29
+ define_attributes
22
30
  end
23
31
 
24
32
  def states
@@ -38,7 +46,7 @@ module RailsStateMachine
38
46
  end
39
47
 
40
48
  def find_event(name)
41
- @events_by_name.fetch(name.to_sym)
49
+ @events_by_name[name.to_sym]
42
50
  end
43
51
 
44
52
  def has_state?(name)
@@ -74,11 +82,26 @@ module RailsStateMachine
74
82
  @model_module.module_eval(&block)
75
83
  end
76
84
 
85
+ def check_if_states_already_defined
86
+ @states_by_name.each do |state_name, _|
87
+ other_state_machines.each do |state_machine|
88
+ if state_machine.has_state?(state_name) && state_machine.prefix == prefix
89
+ raise StateAlreadyDefinedError, "State #{state_name.inspect} has already been defined in the #{state_machine.state_attribute.inspect} state machine. You may use the :prefix option when defining a state machine to avoid that."
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ def other_state_machines
96
+ model.state_machines.except(@state_attribute).values
97
+ end
98
+
77
99
  def define_state_methods
78
100
  state_attribute = @state_attribute
101
+ prefix = prefix_for_method_definition
79
102
  state_names.each do |state_name|
80
103
  model_module_eval do
81
- define_method "#{state_name}?" do
104
+ define_method "#{prefix}#{state_name}?" do
82
105
  state_machine_state_manager(state_attribute).state == state_name.to_s
83
106
  end
84
107
  end
@@ -87,7 +110,7 @@ module RailsStateMachine
87
110
 
88
111
  def define_state_constants
89
112
  state_names.each do |state_name|
90
- model_constant("STATE_#{state_name.upcase}", state_name)
113
+ model_constant("#{@prefix_for_constant_definition}STATE_#{state_name.upcase}", state_name)
91
114
  end
92
115
  end
93
116
 
@@ -125,17 +148,11 @@ module RailsStateMachine
125
148
  end
126
149
  end
127
150
 
128
- def define_model_methods
151
+ def define_attributes
129
152
  state_attribute = @state_attribute
130
153
 
131
- model_module_eval do
132
- define_method :"#{state_attribute}_event=" do |event_name|
133
- state_machine_state_manager(state_attribute).transition_to(event_name)
134
- end
135
-
136
- define_method :"#{state_attribute}_event" do
137
- state_machine_state_manager(state_attribute).next_event&.name
138
- end
154
+ @model.instance_eval do
155
+ attribute :"#{state_attribute}_event", :string
139
156
  end
140
157
  end
141
158
  end
@@ -1,6 +1,7 @@
1
1
  module RailsStateMachine
2
2
  class StateManager
3
3
  attr_accessor :next_event, :state_before_state_event
4
+ attr_reader :state_attribute
4
5
 
5
6
  def initialize(record, state_machine, state_attribute)
6
7
  @record = record
@@ -21,7 +22,10 @@ module RailsStateMachine
21
22
  end
22
23
 
23
24
  def revert
24
- self.state = @state_before_state_event if @next_event
25
+ if @next_event
26
+ self.state = @state_before_state_event
27
+ self.state_event = @next_event.name
28
+ end
25
29
  end
26
30
 
27
31
  def source_state
@@ -32,16 +36,30 @@ module RailsStateMachine
32
36
  end
33
37
  end
34
38
 
35
- def transition_to(event_name)
36
- @next_event = @state_machine.find_event(event_name)
37
- @state_before_state_event = source_state
39
+ def state_event
40
+ @record.public_send(:"#{@state_machine.state_attribute}_event")
41
+ end
38
42
 
39
- # If the event can not transition from source_state, a TransitionNotFoundError will be raised
40
- self.state = @next_event.future_state_name(source_state).to_s
43
+ def state_event=(value)
44
+ @record.public_send(:"#{@state_machine.state_attribute}_event=", value)
41
45
  end
42
46
 
43
47
  def transition_allowed_for?(event_name)
44
- @state_machine.find_event(event_name).allowed_from?(source_state)
48
+ !!@state_machine.find_event(event_name)&.allowed_from?(state)
49
+ end
50
+
51
+ def transition_to(event_name)
52
+ if transition_allowed_for?(event_name)
53
+ self.state_before_state_event = source_state
54
+ event = @state_machine.find_event(event_name)
55
+ self.state = event.future_state_name(state).to_s
56
+ self.state_event = nil
57
+ @next_event = event
58
+
59
+ true
60
+ else
61
+ false
62
+ end
45
63
  end
46
64
  end
47
65
  end
@@ -1,3 +1,3 @@
1
1
  module RailsStateMachine
2
- VERSION = '2.1.1'
2
+ VERSION = '3.0.0'
3
3
  end
@@ -26,5 +26,4 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_development_dependency 'bundler', '~> 1.16'
28
28
  spec.add_development_dependency 'rake', '~> 10.0'
29
- spec.add_development_dependency 'pry-byebug', '~> 3.5'
30
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_state_machine
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arne Hartherz
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-03-16 00:00:00.000000000 Z
12
+ date: 2024-06-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -53,20 +53,6 @@ dependencies:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '10.0'
56
- - !ruby/object:Gem::Dependency
57
- name: pry-byebug
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - "~>"
61
- - !ruby/object:Gem::Version
62
- version: '3.5'
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: '3.5'
70
56
  description: ActiveRecord-bound state machine
71
57
  email:
72
58
  - arne.hartherz@makandra.de
@@ -80,8 +66,6 @@ files:
80
66
  - ".ruby-version"
81
67
  - CHANGELOG.md
82
68
  - Gemfile
83
- - Gemfile.5.1.pg
84
- - Gemfile.5.1.pg.lock
85
69
  - Gemfile.5.2.pg
86
70
  - Gemfile.5.2.pg.lock
87
71
  - Gemfile.6.0.pg
@@ -126,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
110
  - !ruby/object:Gem::Version
127
111
  version: '0'
128
112
  requirements: []
129
- rubygems_version: 3.3.9
113
+ rubygems_version: 3.4.14
130
114
  signing_key:
131
115
  specification_version: 4
132
116
  summary: ActiveRecord-bound state machine
data/Gemfile.5.1.pg DELETED
@@ -1,15 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Runtime dependencies
4
- gem 'rails', '~>5.1.0'
5
- gem 'pg'
6
-
7
- # Development dependencies
8
- gem 'rspec', '~>3.5'
9
- gem 'rake'
10
- gem 'pry-byebug'
11
- gem 'gemika'
12
- gem 'database_cleaner'
13
-
14
- # Gem under test
15
- gem 'rails_state_machine', :path => '.'