gocardless/statesman
56.9
Adequate · 19 September 2026
1.3k
lines of production code
Ruby
primary language
1
measurement over time
What this system is
This system is a Ruby gem library for managing state machines within Rails applications, providing a structured way to define and execute state transitions. It supports persistence via ActiveRecord or in-memory storage, featuring configurable adapters, caching mechanisms, and robust callback systems for handling transition logic and failures. The library includes generators for scaffolding transition models and migrations, along with database-agnostic tools for backfilling state data, ensuring compatibility across various database backends and modern Rails versions.
Features
Added database-agnostic backfill task for most\_recent transitions
A new Rake task (\statesman:backfill\_most\_recent\) is introduced to populate the \most\_recent\ column on transition records. The implementation is designed to be database-agnostic: it detects whether the underlying database supports partial indexes and, if not, sets the column to \nil\ instead of \false\ for older transitions. The task processes records in batches, updates the \updated\_at\ timestamp, and is safe to re-run.
lib/tasks · high confidence
New ActiveRecord and Memory adapters with configurable state caching
The library now includes dedicated \Statesman::Adapters::ActiveRecord\ and \Statesman::Adapters::Memory\ adapters, replacing the previous monolithic implementation. The ActiveRecord adapter introduces a \most\_recent\ column on transition records to efficiently track the current state and supports JSON/JSONB metadata serialization. It also adds a \ConfigureCachedCurrentState\ module, allowing models to cache the current state in a dedicated column for faster lookups, with optional \updated\_at\ timestamp touching. The new \TypeSafeActiveRecordQueries\ module provides a cleaner, type-safe way to include state machine queries (\in\_state\, \not\_in\_state\) into models, while the Memory adapter offers an in-memory implementation for testing or non-persistent use cases.
lib/statesman/adapters · high confidence
New generators for transition models and migrations
The library now includes dedicated Rails generators to scaffold state machine components. The new \ActiveRecordTransitionGenerator\ creates both the transition model file and its corresponding migration, while the \MigrationGenerator\ allows users to add required Statesman attributes to an existing transition class. These generators utilize shared helper logic to correctly handle database-specific configurations, such as JSON column types and default values, ensuring compatibility across different database adapters.
lib/generators/statesman · high confidence
Behavioural changes
Generator templates now include a \`most\_recent\` column and configurable timestamps
The ActiveRecord transition model and migration generators have been updated to include a \most\_recent\ boolean column, which is marked as not null and indexed to efficiently identify the latest transition for a parent record. The generated migration templates now enforce \null: false\ constraints on core columns and timestamps, and conditionally apply partial index syntax for databases that support it. Additionally, the model template now supports configuring the \updated\_timestamp\_column\ and excludes \attr\_accessible\ declarations for Rails 5 and higher, ensuring compatibility with modern Rails versions.
lib/generators/statesman/templates · high confidence
Introduces global configuration and lazy loading for storage adapters
The library now supports global configuration via a new \Statesman.configure\ block, allowing users to set a default storage adapter (e.g., ActiveRecord) and enable MySQL gaplock protection at the application level. To improve startup performance, all core classes and adapters are now lazily loaded using Ruby's \autoload\ mechanism, replacing the previous eager \require\ statements. This change simplifies setup by providing a centralized configuration point while maintaining backward compatibility through a default in-memory adapter.
lib · high confidence
Statesman state machine library updated to v13.3.0
The Statesman gem has been upgraded to version 13.3.0. This release introduces a refactored callback system with dedicated \Callback\ and \Guard\ classes, allowing for more granular control over state transitions via \before\_transition\, \after\_transition\, \after\_transition\_failure\, and \after\_guard\_failure\ hooks. It also adds specific error classes like \TransitionFailedError\ and \GuardFailedError\ to provide detailed context (from/to states, callback source) on failures, and includes configuration options for MySQL gaplock protection and storage adapters.
lib/statesman · high confidence
Test coverage
Added RSpec configuration for ActiveRecord testing; Added comprehensive test coverage for state machine adapters; Added generator specs for ActiveRecord transition and migration generation; Added migration fixtures for the most\_recent column on bacon\_transitions; Added test coverage for core state machine components; Added test support infrastructure for ActiveRecord and generators.
Dependencies
Update dependencies and require Ruby 3.3
The project now requires Ruby 3.3 or higher and updates its development dependencies to support testing against Rails 8.0. Key dependency updates include sqlite3 to \~\> 2.9.0, pg to \<= 1.7, rspec-rails to \~\> 8.0, rspec-its to \~\> 2.0, and gc\_ruboconfig to \~\> 6.0.0. The gemspec has also been updated with new metadata fields and the author information changed to GoCardless.
(dependencies) · high confidence
Housekeeping
Project configuration and development environment setup
The repository now includes standard configuration files to streamline development and testing. A \.rspec\ file sets default RSpec options, while \.rubocop.yml\ and \.rubocop\_todo.yml\ enforce code style using the \gc\_ruboconfig\ gem and target Ruby 3.3. The \.ruby-version\ file specifies Ruby 3.4.5, and a new \Guardfile\ automates running specs and Rubocop on file changes. Additionally, \.gitignore\ has been expanded to exclude common IDE, coverage, and build artifacts, and the \Rakefile\ now includes tasks for running RSpec with CircleCI JUnit formatting support.
(repo-wide) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 57.
Lenses
- Code Health 97
- Architecture 69
- Maturity 54
- Readiness 45
- Security 95
Changes since last survey
- 300 commits — 264 feature/other, 36 fixes
By area
- (root) — 107 commits
- (repo) — 106 commits
- lib/statesman — 50 commits
- .circleci/config.yml — 14 commits
- spec/statesman — 11 commits
- .github/workflows — 6 commits
- docs/COMPATIBILITY.md — 2 commits
- lib/generators — 2 commits
- lib/statesman.rb — 2 commits
Notable commits
- fix: Fix Rubocop errors
- fix: Fix Ruby 2.7 deprecation warning for Proc.new
- fix: Fix to_s on customized errors (#394)
- fix: Fix autoloading the VERSION constant
- fix: Fix broken link
- fix: Fix lint warning in COMPATIBILILTY.md
- fix: Fix logo in README (#430)
- fix: Fix pry dependency cop
- fix: Fix readme examples
- fix: Fix reloading state machine caches
- fix: Fix rubocop complaint
- fix: Fix rubocop offenses and add explanatory comment to the spec
- fix: Fix rubocop violation
- fix: Fix rubocop violations
- fix: Fix statesman index detection
- fix: Fix warning in test
- fix: Fixed issue with transitions using STI (#503)
- fix: Merge branch 'master' into hm-fix-version-autoload
- fix: Merge pull request #354 from hmarr/fix-mysql-statesman-index-detection
- fix: Merge pull request #370 from gocardless/revert-358-cleaner-query-mixin
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
gocardless/statesman was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 3a7e9b7a69a6d627e8e76e84e5c59cd0827755c8 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.