{"id":14955576,"url":"https://github.com/geekq/workflow-activerecord","last_synced_at":"2025-10-06T00:11:59.784Z","repository":{"id":45334200,"uuid":"70488260","full_name":"geekq/workflow-activerecord","owner":"geekq","description":"ActiveRecord/Rails Integration for the Workflow library","archived":false,"fork":false,"pushed_at":"2024-08-01T11:40:06.000Z","size":62,"stargazers_count":36,"open_issues_count":1,"forks_count":14,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2025-04-09T18:17:21.265Z","etag":null,"topics":["aasm","activerecord","rails","rails5","ruby","state-machine"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/geekq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-10T13:03:14.000Z","updated_at":"2025-01-15T16:35:02.000Z","dependencies_parsed_at":"2024-09-24T13:23:42.289Z","dependency_job_id":null,"html_url":"https://github.com/geekq/workflow-activerecord","commit_stats":{"total_commits":59,"total_committers":6,"mean_commits":9.833333333333334,"dds":0.288135593220339,"last_synced_commit":"05b7260f71a80f3d46dd27db2c197f6ed991bd25"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekq%2Fworkflow-activerecord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekq%2Fworkflow-activerecord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekq%2Fworkflow-activerecord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekq%2Fworkflow-activerecord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geekq","download_url":"https://codeload.github.com/geekq/workflow-activerecord/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248085321,"owners_count":21045139,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aasm","activerecord","rails","rails5","ruby","state-machine"],"created_at":"2024-09-24T13:11:23.666Z","updated_at":"2025-10-06T00:11:54.755Z","avatar_url":"https://github.com/geekq.png","language":"Ruby","readme":"[![Version](https://img.shields.io/gem/v/workflow-activerecord.svg)](https://rubygems.org/gems/workflow-activerecord)\n[![Test](https://github.com/geekq/workflow-activerecord/actions/workflows/test.yml/badge.svg)](https://github.com/geekq/workflow-activerecord/actions/workflows/test.yml)\n[![Code Climate](https://codeclimate.com/github/geekq/workflow-activerecord/badges/gpa.svg)](https://codeclimate.com/github/geekq/workflow-activerecord)\n[![Test Coverage](https://codeclimate.com/github/geekq/workflow-activerecord/badges/coverage.svg)](https://codeclimate.com/github/geekq/workflow-activerecord/coverage)\n\n# workflow-activerecord\n\n**ActiveRecord/Rails Integration for the Workflow library**\n\nMajor+minor versions of workflow-activerecord are based on the oldest\ncompatible ActiveRecord API. To use [`workflow`][workflow] with\nRails/ActiveRecord 6.*, 7.* please use:\n\n    gem 'workflow-activerecord', '~\u003e 6.0'\n\nThis will also automatically include the newest compatible version of\nthe core 'workflow' gem. But you can also choose a specific version:\n\n    gem 'workflow', '~\u003e 2.0'\n    gem 'workflow-activerecord', '~\u003e 4.1'\n\nPlease also have a look at [the sample application][]!\n\nFor detailed introduction into workflow DSL please read the\n[`workflow` README][workflow]!\n\n[workflow]: https://github.com/geekq/workflow\n[the sample application]: https://github.com/geekq/workflow-rails-sample\n\n\nState persistence with ActiveRecord\n-----------------------------------\n\nWorkflow library can handle the state persistence fully automatically. You\nonly need to define a string field on the table called `workflow_state`\nand include the workflow mixin in your model class as usual:\n\n    class Order \u003c ApplicationRecord\n      include WorkflowActiverecord\n      workflow do\n        # list states and transitions here\n      end\n    end\n\nOn a database record loading all the state check methods e.g.\n`article.state`, `article.awaiting_review?` are immediately available.\nFor new records or if the `workflow_state` field is not set the state\ndefaults to the first state declared in the workflow specification. In\nour example it is `:new`, so `Article.new.new?` returns true and\n`Article.new.approved?` returns false.\n\nAt the end of a successful state transition like `article.approve!` the\nnew state is immediately saved in the database.\n\nYou can change this behaviour by overriding `persist_workflow_state`\nmethod.\n\n### Scopes\n\nWorkflow library also adds automatically generated scopes with names based on\nstates names:\n\n    class Order \u003c ApplicationRecord\n      include WorkflowActiverecord\n      workflow do\n        state :approved\n        state :pending\n      end\n    end\n\n    # returns all orders with `approved` state\n    Order.with_approved_state\n\n    # returns all orders with `pending` state\n    Order.with_pending_state\n\n\n### Custom workflow database column\n\n[meuble](http://imeuble.info/) contributed a solution for using\ncustom persistence column easily, e.g. for a legacy database schema:\n\n    class LegacyOrder \u003c ApplicationRecord\n      include WorkflowActiverecord\n\n      workflow_column :foo_bar # use this legacy database column for\n                               # persistence\n    end\n\n\n\n### Single table inheritance\n\nSingle table inheritance is also supported. Descendant classes can either\ninherit the workflow definition from the parent or override with its own\ndefinition.\n\n\nCustom Versions of Existing Adapters\n------------------------------------\n\nOther adapters (such as a custom ActiveRecord plugin) can be selected by adding a `workflow_adapter` class method, eg.\n\n```ruby\nclass Example \u003c ApplicationRecord\n  def self.workflow_adapter\n    MyCustomAdapter\n  end\n  include Workflow\n\n  # ...\nend\n```\n\n(The above will include `MyCustomAdapter` *instead* of the default\n`WorkflowActiverecord` adapter.)\n\n\nMultiple Workflows\n------------------\n\nI am frequently asked if it's possible to represent multiple \"workflows\"\nin an ActiveRecord class.\n\nThe solution depends on your business logic and how you want to\nstructure your implementation.\n\n### Use Single Table Inheritance\n\nOne solution can be to do it on the class level and use a class\nhierarchy. You can use [single table inheritance][STI] so there is only\nsingle `orders` table in the database. Read more in the chapter \"Single\nTable Inheritance\" of the [ActiveRecord documentation][ActiveRecord].\nThen you define your different classes:\n\n    class Order \u003c ActiveRecord::Base\n      include WorkflowActiverecord\n    end\n\n    class SmallOrder \u003c Order\n      workflow do\n        # workflow definition for small orders goes here\n      end\n    end\n\n    class BigOrder \u003c Order\n      workflow do\n        # workflow for big orders, probably with a longer approval chain\n      end\n    end\n\n\n### Individual workflows for objects\n\nAnother solution would be to connect different workflows to object\ninstances via metaclass, e.g.\n\n    # Load an object from the database\n    booking = Booking.find(1234)\n\n    # Now define a workflow - exclusively for this object,\n    # probably depending on some condition or database field\n    if # some condition\n      class \u003c\u003c booking\n        include WorkflowActiverecord\n        workflow do\n          state :state1\n          state :state2\n        end\n      end\n    # if some other condition, use a different workflow\n\nYou can also encapsulate this in a class method or even put in some\nActiveRecord callback. Please also have a look at [the full working\nexample][multiple_workflow_test]!\n\n### on_transition\n\nYou can have a look at an advanced [`on_transition`][] example in\n[this test file][advanced_hooks_and_validation_test].\n\n[STI]: http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html\n[ActiveRecord]: http://api.rubyonrails.org/classes/ActiveRecord/Base.html\n[multiple_workflow_test]: https://github.com/geekq/workflow-activerecord/blob/develop/test/multiple_workflows_test.rb\n[`on_transition`]: https://github.com/geekq/workflow#on_transition\n[advanced_hooks_and_validation_test]: http://github.com/geekq/workflow-activerecord/blob/develop/test/advanced_hooks_and_validation_test.rb\n\n\n### Handling the state transition in a transaction\n\nYou might want to perform the state transition in a database transaction,\nso that the state is persisted atomically with all the other attributes.\nTo do so, define a module:\n\n```ruby\nmodule TransitionTransaction\n  def process_event!(name, *, **)\n    transaction { super(name, *, **) }\n  end\nend\n```\n\nand then prepend it in your model:\n\n```ruby\nclass Task\n  workflow do\n    ...\n  end\n\n  prepend TransitionTransaction\nend\n```\n\nChangelog\n---------\n\n### New in the version 6.0.0\n\n* GH-14 retire Ruby 2.6 and Rails 5.* and older since they have reached end of\n  live; please use workflow-activerecord 4.1.9, if you still depend on\n  those versions\n\n### New in the version 4.1.9\n\n* GH-13 Switch CI (continuous integration) from travis-CI to GitHub\n* Tested Rails 7.0 support\n\n\nSupport\n-------\n\n### Reporting bugs\n\n\u003chttp://github.com/geekq/workflow-activerecord/issues\u003e\n\n\nAbout\n-----\n\nAuthor: Vladimir Dobriakov, \u003chttps://infrastructure-as-code.de\u003e\n\nCopyright (c) 2010-2024 Vladimir Dobriakov and Contributors\n\nCopyright (c) 2008-2009 Vodafone\n\nCopyright (c) 2007-2008 Ryan Allen, FlashDen Pty Ltd\n\nBased on the work of Ryan Allen and Scott Barron\n\nLicensed under MIT license, see the LICENSE file.\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeekq%2Fworkflow-activerecord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeekq%2Fworkflow-activerecord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeekq%2Fworkflow-activerecord/lists"}