statesman 12.1.0 → 13.1.0

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/devcontainer.json +31 -0
  3. data/.devcontainer/docker-compose.yml +39 -0
  4. data/.github/workflows/tests.yml +42 -24
  5. data/.gitignore +1 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +1 -4
  8. data/.rubocop_todo.yml +23 -38
  9. data/.ruby-version +1 -1
  10. data/CHANGELOG.md +31 -7
  11. data/Gemfile +15 -1
  12. data/README.md +47 -26
  13. data/docs/COMPATIBILITY.md +1 -1
  14. data/lib/generators/statesman/active_record_transition_generator.rb +4 -5
  15. data/lib/generators/statesman/generator_helpers.rb +28 -14
  16. data/lib/generators/statesman/migration_generator.rb +4 -8
  17. data/lib/generators/statesman/templates/active_record_transition_model.rb.erb +3 -3
  18. data/lib/generators/statesman/templates/create_migration.rb.erb +3 -2
  19. data/lib/generators/statesman/templates/update_migration.rb.erb +3 -2
  20. data/lib/statesman/adapters/active_record.rb +9 -5
  21. data/lib/statesman/adapters/active_record_transition.rb +6 -0
  22. data/lib/statesman/adapters/memory.rb +1 -1
  23. data/lib/statesman/adapters/memory_transition.rb +3 -1
  24. data/lib/statesman/exceptions.rb +2 -0
  25. data/lib/statesman/guard.rb +1 -1
  26. data/lib/statesman/machine.rb +16 -0
  27. data/lib/statesman/version.rb +1 -1
  28. data/spec/generators/statesman/active_record_transition_generator_spec.rb +18 -9
  29. data/spec/generators/statesman/migration_generator_spec.rb +20 -13
  30. data/spec/spec_helper.rb +1 -0
  31. data/spec/statesman/adapters/active_record_queries_spec.rb +2 -2
  32. data/spec/statesman/adapters/active_record_spec.rb +8 -6
  33. data/spec/statesman/adapters/memory_transition_spec.rb +4 -2
  34. data/spec/statesman/adapters/shared_examples.rb +4 -3
  35. data/spec/statesman/adapters/type_safe_active_record_queries_spec.rb +1 -1
  36. data/spec/statesman/exceptions_spec.rb +10 -0
  37. data/spec/statesman/machine_spec.rb +46 -12
  38. data/spec/support/active_record.rb +18 -2
  39. data/spec/support/generators_shared_examples.rb +2 -2
  40. data/statesman.gemspec +1 -15
  41. metadata +7 -202
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d49f534086023febd344f7eb73b162903a28e3fd77ee430856d42242aafda37c
4
- data.tar.gz: aba9670be235de98143f0a2ae0d15b9b7b32c8a9699901049e5cd9d931e29981
3
+ metadata.gz: f93bd968475f6cfd090311f9998a2350993df852aa3796fab5d3b52f962d6147
4
+ data.tar.gz: 3789c10d55df44ee6e921f9d2297d7d0e0767f42521309ac14aed8e49a0986a8
5
5
  SHA512:
6
- metadata.gz: d68959bd95e90bd0a986de5dd7197d21ac5535a5500d5d528b599fd07d26611125ce7e926f33efb5140f2ecbffa1c78dbb66e6d5f2209eeabe95ee49a4a862f8
7
- data.tar.gz: 449e98a18f512eaff9a1ea500f9415b016bc8e775f7e1b1a7b9ffc393038112b3689ff4e7d364cbff9be6d23e3c4768d373dda3df7339249b53aa7a9d2e33136
6
+ metadata.gz: 13b9e129ec5bb984066a05c408ee99c9965861775269bab232e6aac86ee75b5c5485a14ccc8476b3b96d0bc383cc68a1f67d32cf9d3eea575478e25ed0245d56
7
+ data.tar.gz: d88507f263405847ea99f8a7cc88ec4e63c3a82addcef3a20e9c0e1c83372df38868278459702c0855e535d7ebca031e18ddaee32031b0beb162932963156325
@@ -0,0 +1,31 @@
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/ruby
3
+ {
4
+ "name": "Ruby",
5
+ "dockerComposeFile": "docker-compose.yml",
6
+ "service": "ruby",
7
+ "workspaceFolder": "/workspace",
8
+ // Environment variables for database connections
9
+ "containerEnv": {
10
+ "POSTGRES_URL": "postgresql://postgres:password@postgres:5432/statesman_dev",
11
+ "MYSQL_URL": "mysql2://root:password@mysql:3306/statesman_dev",
12
+ "PGHOST": "postgres",
13
+ "PGPORT": "5432",
14
+ "PGDATABASE": "statesman_dev",
15
+ "PGUSER": "postgres",
16
+ "PGPASSWORD": "password",
17
+ "MYSQL_HOST": "mysql",
18
+ "MYSQL_PORT": "3306",
19
+ "MYSQL_DATABASE": "statesman_dev",
20
+ "MYSQL_USER": "root",
21
+ "MYSQL_PASSWORD": "password"
22
+ },
23
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
24
+ // "forwardPorts": [],
25
+ // Use 'postCreateCommand' to run commands after the container is created.
26
+ "postCreateCommand": "sudo apt-get update && sudo apt-get install -y postgresql-client default-mysql-client && sudo chown -R vscode:vscode /usr/local/rvm/gems/default && bundle install",
27
+ // Configure tool-specific properties.
28
+ // "customizations": {},
29
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
30
+ // "remoteUser": "root"
31
+ }
@@ -0,0 +1,39 @@
1
+ version: '3.8'
2
+
3
+ services:
4
+ ruby:
5
+ image: mcr.microsoft.com/devcontainers/ruby:1-3.4-bullseye
6
+ volumes:
7
+ - ..:/workspace:cached
8
+ - gem-cache:/usr/local/rvm/gems/default
9
+ command: sleep infinity
10
+ depends_on:
11
+ - postgres
12
+ - mysql
13
+
14
+ postgres:
15
+ image: postgres:15
16
+ restart: unless-stopped
17
+ environment:
18
+ POSTGRES_PASSWORD: password
19
+ POSTGRES_DB: statesman_dev
20
+ volumes:
21
+ - postgres-data:/var/lib/postgresql/data
22
+ expose:
23
+ - "5432"
24
+
25
+ mysql:
26
+ image: mysql:8.0
27
+ restart: unless-stopped
28
+ environment:
29
+ MYSQL_ROOT_PASSWORD: password
30
+ MYSQL_DATABASE: statesman_dev
31
+ volumes:
32
+ - mysql-data:/var/lib/mysql
33
+ expose:
34
+ - "3306"
35
+
36
+ volumes:
37
+ postgres-data:
38
+ mysql-data:
39
+ gem-cache:
@@ -3,8 +3,9 @@ name: tests
3
3
  on:
4
4
  push:
5
5
  branches:
6
- - "master"
6
+ - master
7
7
  pull_request:
8
+ types: [opened, reopened, synchronize]
8
9
 
9
10
  concurrency:
10
11
  group: ${{ github.workflow }}-${{ github.ref }}
@@ -14,28 +15,47 @@ jobs:
14
15
  rubocop:
15
16
  runs-on: ubuntu-latest
16
17
  steps:
17
- - uses: actions/checkout@v3
18
+ - uses: actions/checkout@v5
18
19
  - uses: ruby/setup-ruby@v1
19
20
  with:
20
21
  bundler-cache: true
21
22
  - run: bundle exec rubocop --extra-details --display-style-guide --parallel --force-exclusion
22
23
 
24
+ sqlite:
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ ruby-version: ["3.2", "3.3", "3.4", "3.5"]
29
+ rails-version:
30
+ - "7.1"
31
+ - "7.2"
32
+ - "8.0"
33
+ - "main"
34
+ runs-on: ubuntu-latest
35
+ env:
36
+ RAILS_VERSION: ${{ matrix.rails-version }}
37
+ steps:
38
+ - uses: actions/checkout@v5
39
+ - name: Set up Ruby
40
+ uses: ruby/setup-ruby@v1
41
+ with:
42
+ bundler-cache: true
43
+ ruby-version: "${{ matrix.ruby-version }}"
44
+ - name: Run specs
45
+ run: |
46
+ bundle exec rspec --profile --format progress --format RSpec::Github::Formatter
47
+
23
48
  postgres:
24
49
  strategy:
25
50
  fail-fast: false
26
51
  matrix:
27
- ruby-version: ["3.0", "3.1", "3.2", "3.3"]
52
+ ruby-version: ["3.2", "3.3", "3.4", "3.5"]
28
53
  rails-version:
29
- - "6.1.7.6"
30
- - "7.0.8"
31
- - "7.1.1"
54
+ - "7.1"
55
+ - "7.2"
56
+ - "8.0"
32
57
  - "main"
33
- postgres-version: ["12", "13", "14", "15", "16"]
34
- exclude:
35
- - ruby-version: "3.2"
36
- rails-version: "6.1.7.6"
37
- - ruby-version: "3.3"
38
- rails-version: "6.1.7.6"
58
+ postgres-version: ["14", "15", "16", "17"]
39
59
  runs-on: ubuntu-latest
40
60
  services:
41
61
  postgres:
@@ -54,8 +74,9 @@ jobs:
54
74
  env:
55
75
  DATABASE_URL: postgres://postgres:statesman@localhost/statesman_test
56
76
  DATABASE_DEPENDENCY_PORT: "5432"
77
+ RAILS_VERSION: ${{ matrix.rails-version }}
57
78
  steps:
58
- - uses: actions/checkout@v3
79
+ - uses: actions/checkout@v5
59
80
  - name: Set up Ruby
60
81
  uses: ruby/setup-ruby@v1
61
82
  with:
@@ -69,18 +90,14 @@ jobs:
69
90
  strategy:
70
91
  fail-fast: false
71
92
  matrix:
72
- ruby-version: ["3.0", "3.1", "3.2", "3.3"]
93
+ ruby-version: ["3.2", "3.3", "3.4", "3.5"]
73
94
  rails-version:
74
- - "6.1.7.6"
75
- - "7.0.8"
76
- - "7.1.1"
95
+ - "7.1"
96
+ - "7.2"
97
+ - "8.0"
77
98
  - "main"
78
- mysql-version: ["8.0", "8.2"]
79
- exclude:
80
- - ruby-version: "3.2"
81
- rails-version: "6.1.7.6"
82
- - ruby-version: "3.3"
83
- rails-version: "6.1.7.6"
99
+ mysql-version: ["8.0", "8.4", "9.4"]
100
+
84
101
  runs-on: ubuntu-latest
85
102
  services:
86
103
  mysql:
@@ -100,8 +117,9 @@ jobs:
100
117
  env:
101
118
  DATABASE_URL: mysql2://foobar:password@127.0.0.1/statesman_test
102
119
  DATABASE_DEPENDENCY_PORT: "3306"
120
+ RAILS_VERSION: ${{ matrix.rails-version }}
103
121
  steps:
104
- - uses: actions/checkout@v3
122
+ - uses: actions/checkout@v5
105
123
  - name: Set up Ruby
106
124
  uses: ruby/setup-ruby@v1
107
125
  with:
data/.gitignore CHANGED
@@ -66,3 +66,4 @@ Gemfile.lock
66
66
 
67
67
  # JetBrains
68
68
  .idea
69
+ spec/support/generator-tmp/
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --require spec_helper
2
+ --format progress
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ inherit_gem:
4
4
  gc_ruboconfig: rubocop.yml
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 3.0
7
+ TargetRubyVersion: 3.2
8
8
  NewCops: enable
9
9
 
10
10
  Metrics/AbcSize:
@@ -15,6 +15,3 @@ Metrics/CyclomaticComplexity:
15
15
 
16
16
  Metrics/PerceivedComplexity:
17
17
  Max: 11
18
-
19
- Gemspec/DevelopmentDependencies:
20
- Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,56 +1,47 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2021-08-09 15:32:40 UTC using RuboCop version 1.18.4.
3
+ # on 2025-08-29 17:37:05 UTC using RuboCop version 1.80.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
9
  # Offense count: 1
10
- # Configuration parameters: Include.
11
- # Include: **/*.gemspec
12
- Gemspec/RequiredRubyVersion:
13
- Exclude:
14
- - 'statesman.gemspec'
15
-
16
- # Offense count: 1
10
+ # Configuration parameters: AllowedParentClasses.
17
11
  Lint/MissingSuper:
18
12
  Exclude:
19
13
  - 'lib/statesman/adapters/active_record_queries.rb'
20
14
 
21
- # Offense count: 5
22
- # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
23
- Metrics/AbcSize:
24
- Max: 20
15
+ # Offense count: 2
16
+ # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
17
+ # AllowedMethods: call
18
+ # WaywardPredicates: nonzero?
19
+ Naming/PredicateMethod:
20
+ Exclude:
21
+ - 'lib/statesman/callback.rb'
25
22
 
26
23
  # Offense count: 1
27
- # Configuration parameters: IgnoredMethods.
28
- Metrics/CyclomaticComplexity:
29
- Max: 8
30
-
31
- # Offense count: 3
32
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
33
- Metrics/MethodLength:
34
- Max: 14
24
+ # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
25
+ # NamePrefix: is_, has_, have_, does_
26
+ # ForbiddenPrefixes: is_, has_, have_, does_
27
+ # AllowedMethods: is_a?
28
+ # MethodDefinitionMacros: define_method, define_singleton_method
29
+ Naming/PredicatePrefix:
30
+ Exclude:
31
+ - 'spec/**/*'
32
+ - 'lib/statesman/adapters/active_record.rb'
35
33
 
36
- # Offense count: 11
34
+ # Offense count: 15
37
35
  # Configuration parameters: CountAsOne.
38
36
  RSpec/ExampleLength:
39
37
  Max: 14
40
38
 
41
- # Offense count: 7
39
+ # Offense count: 5
42
40
  RSpec/ExpectInHook:
43
41
  Exclude:
44
42
  - 'spec/statesman/adapters/active_record_spec.rb'
45
43
  - 'spec/statesman/machine_spec.rb'
46
44
 
47
- # Offense count: 1
48
- # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
49
- # Include: **/*_spec*rb*, **/spec/**/*
50
- RSpec/FilePath:
51
- Exclude:
52
- - 'spec/statesman/exceptions_spec.rb'
53
-
54
45
  # Offense count: 1
55
46
  # Configuration parameters: AssignmentOnly.
56
47
  RSpec/InstanceVariable:
@@ -80,11 +71,12 @@ RSpec/MessageSpies:
80
71
  Exclude:
81
72
  - 'spec/statesman/callback_spec.rb'
82
73
 
83
- # Offense count: 14
74
+ # Offense count: 20
84
75
  RSpec/MultipleExpectations:
85
76
  Max: 3
86
77
 
87
- # Offense count: 49
78
+ # Offense count: 64
79
+ # Configuration parameters: AllowedGroups.
88
80
  RSpec/NestedGroups:
89
81
  Max: 6
90
82
 
@@ -93,13 +85,6 @@ RSpec/RepeatedExampleGroupBody:
93
85
  Exclude:
94
86
  - 'spec/statesman/exceptions_spec.rb'
95
87
 
96
- # Offense count: 12
97
- RSpec/ScatteredSetup:
98
- Exclude:
99
- - 'spec/statesman/adapters/active_record_spec.rb'
100
- - 'spec/statesman/adapters/shared_examples.rb'
101
- - 'spec/statesman/machine_spec.rb'
102
-
103
88
  # Offense count: 7
104
89
  # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
105
90
  RSpec/VerifiedDoubles:
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.3.0
1
+ 3.4.5
data/CHANGELOG.md CHANGED
@@ -1,9 +1,33 @@
1
1
  # Changelog
2
+
2
3
  <!-- markdownlint-disable no-duplicate-heading -->
3
4
 
4
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
7
 
8
+ ## v13.1.0 9th October 2025
9
+
10
+ ### Added
11
+
12
+ - State constants for defining available states [#515](https://github.com/gocardless/statesman/pull/515)
13
+ - from_state method to transition history for easier access to previous states [#493](https://github.com/gocardless/statesman/pull/493)
14
+
15
+ ### Fixed
16
+
17
+ - Fixed transition model generator for namespaced models [#555](https://github.com/gocardless/statesman/pull/555)
18
+
19
+ ### Changed
20
+
21
+ - Updated README and clarified wording [#444](https://github.com/gocardless/statesman/pull/444)
22
+
23
+ ## v13.0.0 29th August 2025
24
+
25
+ ### Changes
26
+
27
+ - Remove support for Rails 6.1 and 7, add support for Rails 8
28
+ - Remove support for PostgreSQL < 13, add support for PostgreSQL 17
29
+ - Remove support for Ruby 3.0, 3.1, add support for Ruby 3.4 and 3.5
30
+
7
31
  ## v12.1.0 5th January 2024
8
32
 
9
33
  ### Fixed
@@ -44,7 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
44
68
 
45
69
  ### Changed
46
70
 
47
- - Calling `active_record.reload` resets the adapater's internal cache
71
+ - Calling `active_record.reload` resets the adapter's internal cache
48
72
 
49
73
  ## v10.2.1 3rd April 2023
50
74
 
@@ -154,7 +178,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
154
178
  ### Fixed
155
179
 
156
180
  - Fix `to_s` on `TransitionFailedError` & `GuardFailedError`. `.message` and
157
- `.to_s` diverged when `from` and `to` accessors where added in v4.1.3
181
+ `.to_s` diverged when `from` and `to` accessors where added in v4.1.3
158
182
 
159
183
  ## v7.0.1, 8th Jan 2020
160
184
 
@@ -258,7 +282,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
258
282
  ### Fixed
259
283
 
260
284
  - Fixes an issue with `after_commit` transition blocks that where being
261
- executed even if the transaction rolled back. ([patch](https://github.com/gocardless/statesman/pull/338) by [@matid](https://github.com/matid))
285
+ executed even if the transaction rolled back. ([patch](https://github.com/gocardless/statesman/pull/338) by [@matid](https://github.com/matid))
262
286
 
263
287
  ### Changed
264
288
 
@@ -269,8 +293,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
269
293
  ### Changed
270
294
 
271
295
  - Expose `most_recent_transition_join` - ActiveRecords `or` requires that both
272
- sides of the query match up. Exposing this methods makes things easier if
273
- one side of the `or` uses `in_state` or `not_in_state`. (patch by [@adambutler](https://github.com/adambutler))
296
+ sides of the query match up. Exposing this methods makes things easier if
297
+ one side of the `or` uses `in_state` or `not_in_state`. (patch by [@adambutler](https://github.com/adambutler))
274
298
  - Various Readme and CI related changes.
275
299
 
276
300
  ## v3.4.1, 14 February 2018 ❤️
@@ -450,7 +474,7 @@ No changes from v1.0.0.beta2
450
474
 
451
475
  ### Fixed
452
476
 
453
- - `ActiveRecordModel.in_state` and `ActiveRecordModel.not_in_state` now handle inital states correctly (patch by [@isaacseymour](https://github.com/isaacseymour))
477
+ - `ActiveRecordModel.in_state` and `ActiveRecordModel.not_in_state` now handle initial states correctly (patch by [@isaacseymour](https://github.com/isaacseymour))
454
478
 
455
479
  ### Added
456
480
 
@@ -520,7 +544,7 @@ No changes from v1.0.0.beta2
520
544
  ### Added
521
545
 
522
546
  - Adds after_commit flag to after_transition for callbacks to be executed after the transaction has been
523
- committed on the ActiveRecord adapter. These callbacks will still be executed on non transactional adapters.
547
+ committed on the ActiveRecord adapter. These callbacks will still be executed on non transactional adapters.
524
548
 
525
549
  ## v0.3.0, 20 February 2014
526
550
 
data/Gemfile CHANGED
@@ -8,9 +8,23 @@ if ENV['RAILS_VERSION'] == 'main'
8
8
  gem "rails", git: "https://github.com/rails/rails", branch: "main"
9
9
  elsif ENV['RAILS_VERSION']
10
10
  gem "rails", "~> #{ENV['RAILS_VERSION']}"
11
+ else
12
+ gem "rails", "~> 8.0"
11
13
  end
12
14
 
13
- group :development do
15
+ group :development, :test do
16
+ gem "ammeter", "~> 1.1"
17
+ gem "bundler", "~> 2"
18
+ gem "gc_ruboconfig", "~> 5.0.0"
19
+ gem "mysql2", ">= 0.4", "< 0.6"
20
+ gem "pg", ">= 0.18", "<= 1.7"
14
21
  gem "pry"
22
+ gem "rake", "~> 13.3.0"
23
+ gem "rspec", "~> 3.1"
24
+ gem "rspec-github", "~> 3.0.0"
25
+ gem "rspec-its", "~> 2.0"
26
+ gem "rspec-rails", "~> 8.0"
27
+ gem "sqlite3", "~> 2.7.3"
15
28
  gem "test-unit", "~> 3.3"
29
+ gem "timecop", "~> 0.9.1"
16
30
  end
data/README.md CHANGED
@@ -33,7 +33,7 @@ protection.
33
33
  To get started, just add Statesman to your `Gemfile`, and then run `bundle`:
34
34
 
35
35
  ```ruby
36
- gem 'statesman', '~> 12.0.0'
36
+ gem 'statesman', '~> 13.0.0'
37
37
  ```
38
38
 
39
39
  ## Usage
@@ -233,12 +233,14 @@ or 5. To do that
233
233
  t.json :metadata, default: {}
234
234
  ```
235
235
 
236
- - Remove the `include Statesman::Adapters::ActiveRecordTransition` statement from
237
- your transition model. (If you want to customise your transition class's "updated
238
- timestamp column", as described above, you should define a
239
- `.updated_timestamp_column` method on your class and return the name of the column
240
- as a symbol, or `nil` if you don't want to record an updated timestamp on
241
- transitions.)
236
+ * Remove the `include Statesman::Adapters::ActiveRecordTransition` statement from
237
+ your transition model, which would've instructed ActiveRecord to serialize the
238
+ metadata.
239
+ * The module that you just removed enables customizing the updatated timestamp column
240
+ as described above. Having removed it, if you want to customise your transition class's
241
+ "updated timestamp column", you should define a `.updated_timestamp_column` method on
242
+ your class and return the name of the column as a symbol, or `nil` if you don't want
243
+ to record an updated timestamp on transitions.
242
244
 
243
245
  ## Configuration
244
246
 
@@ -256,6 +258,23 @@ ActiveRecord adapter.
256
258
 
257
259
  Statesman will fallback to memory unless you specify a transition_class when instantiating your state machine. This allows you to only persist transitions on certain state machines in your app.
258
260
 
261
+ ### `initial_transition`
262
+
263
+ ```ruby
264
+ def state_machine
265
+ @state_machine ||= OrderStateMachine.new(self, transition_class: OrderTransition,
266
+ association_name: :transitions,
267
+ initial_transition: true)
268
+ end
269
+ ```
270
+
271
+ By default Statesman does not record a transition to the initial state of the state machine.
272
+
273
+ You can configure Statesman to record a transition to the initial state, this will allow you to:
274
+ - Keep an accurate record of the initial state even if configuration changes
275
+ - Keep a record of how long the state machine spent in the initial state
276
+ - Utilise a transition hook for the transition to the initial state
277
+
259
278
  ## Class methods
260
279
 
261
280
  ### `Machine.state`
@@ -390,6 +409,24 @@ Machine.successors
390
409
  }
391
410
  ```
392
411
 
412
+ ## Class constants
413
+ Adding a state to a state machine will automatically create a constant for the value, for example:
414
+ ```ruby
415
+ class OrderStateMachine
416
+ include Statesman::Machine
417
+
418
+ state :pending, initial: true
419
+ state :checking_out
420
+ state :cancelled
421
+
422
+ # Constants created as a side effect of adding state
423
+ transition from: PENDING, to: [CHECKING_OUT, CANCELLED]
424
+ end
425
+
426
+ OrderStateMachine::PENDING #=> "pending"
427
+ OrderStateMachine::CHECKING_OUT # => "checking_out"
428
+ ```
429
+
393
430
  ## Instance methods
394
431
 
395
432
  ### `Machine#current_state`
@@ -494,7 +531,7 @@ Raised if:
494
531
  ### Runtime errors
495
532
 
496
533
  These errors are raised by `transition_to!`. Using `transition_to` will
497
- supress `GuardFailedError` and `TransitionFailedError` and return `false` instead.
534
+ suppress `GuardFailedError` and `TransitionFailedError` and return `false` instead.
498
535
 
499
536
  #### GuardFailedError
500
537
 
@@ -524,8 +561,8 @@ model and passing in `transition_class` and `initial_state` as options.
524
561
 
525
562
  In 4.1.2 and below, these two options had to be defined as methods on the model,
526
563
  but 5.0.0 and above allow this style of configuration as well.
527
- The old method pollutes the model with extra class methods, and is deprecated,
528
- to be removed in 6.0.0.
564
+ The old way pollutes the model with extra class methods, and is deprecated,
565
+ to be removed in the future.
529
566
 
530
567
  ```ruby
531
568
  class Order < ActiveRecord::Base
@@ -596,22 +633,6 @@ Given a field `foo` that was stored in the metadata, you can access it like so:
596
633
  model_instance.state_machine.last_transition.metadata["foo"]
597
634
  ```
598
635
 
599
- ### Events
600
-
601
- Used to using a state machine with "events"? Support for events is provided by
602
- the [statesman-events](https://github.com/gocardless/statesman-events) gem. Once
603
- that's included in your Gemfile you can include event functionality in your
604
- state machine as follows:
605
-
606
- ```ruby
607
- class OrderStateMachine
608
- include Statesman::Machine
609
- include Statesman::Events
610
-
611
- ...
612
- end
613
- ```
614
-
615
636
  ### Deleting records
616
637
 
617
638
  If you need to delete the Parent model regularly you will need to change
@@ -2,7 +2,7 @@
2
2
 
3
3
  Our goal as Statesman maintainers is for the library to be compatible with all supported versions of Ruby and Rails.
4
4
 
5
- Specifically, any CRuby/MRI version that has not received an End of Life notice ([e.g. this notice for Ruby 2.1](https://www.ruby-lang.org/en/news/2017/04/01/support-of-ruby-2-1-has-ended/)) is supported. Similarly, any version of Rails listed as currently supported on [this page](http://guides.rubyonrails.org/maintenance_policy.html) is one we aim to support in Statesman.
5
+ Specifically, any CRuby/MRI version that has not received an [End of Life notice](https://endoflife.date/ruby)) is supported. Similarly, any version of Rails listed as currently supported on [this page](https://endoflife.date/rails) is one we aim to support in Statesman.
6
6
 
7
7
  To that end, [our build matrix](../.github/workflows/tests.yml) includes all these versions.
8
8
 
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails/generators"
4
+ require "rails/generators/active_record"
4
5
  require "generators/statesman/generator_helpers"
5
6
 
6
7
  module Statesman
7
8
  class ActiveRecordTransitionGenerator < Rails::Generators::Base
8
9
  include Statesman::GeneratorHelpers
10
+ include ActiveRecord::Generators::Migration
9
11
 
10
12
  desc "Create an ActiveRecord-based transition model" \
11
13
  "with the required attributes"
@@ -16,14 +18,11 @@ module Statesman
16
18
  source_root File.expand_path("templates", __dir__)
17
19
 
18
20
  def create_model_file
19
- template("create_migration.rb.erb", migration_file_name)
20
21
  template("active_record_transition_model.rb.erb", model_file_name)
21
22
  end
22
23
 
23
- private
24
-
25
- def migration_file_name
26
- "db/migrate/#{next_migration_number}_create_#{table_name}.rb"
24
+ def create_migration_file
25
+ migration_template("create_migration.rb.erb", File.join(db_migrate_path, "create_#{table_name}.rb"))
27
26
  end
28
27
  end
29
28
  end