Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/geekq/workflow-activerecord
ActiveRecord/Rails Integration for the Workflow library
https://github.com/geekq/workflow-activerecord
aasm activerecord rails rails5 ruby state-machine
Last synced: 6 days ago
JSON representation
ActiveRecord/Rails Integration for the Workflow library
- Host: GitHub
- URL: https://github.com/geekq/workflow-activerecord
- Owner: geekq
- License: mit
- Created: 2016-10-10T13:03:14.000Z (over 8 years ago)
- Default Branch: develop
- Last Pushed: 2024-08-01T11:40:06.000Z (5 months ago)
- Last Synced: 2024-12-28T00:13:47.437Z (13 days ago)
- Topics: aasm, activerecord, rails, rails5, ruby, state-machine
- Language: Ruby
- Homepage:
- Size: 60.5 KB
- Stars: 35
- Watchers: 2
- Forks: 13
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![Version](https://img.shields.io/gem/v/workflow-activerecord.svg)](https://rubygems.org/gems/workflow-activerecord)
[![Test](https://github.com/geekq/workflow-activerecord/actions/workflows/test.yml/badge.svg)](https://github.com/geekq/workflow-activerecord/actions/workflows/test.yml)
[![Code Climate](https://codeclimate.com/github/geekq/workflow-activerecord/badges/gpa.svg)](https://codeclimate.com/github/geekq/workflow-activerecord)
[![Test Coverage](https://codeclimate.com/github/geekq/workflow-activerecord/badges/coverage.svg)](https://codeclimate.com/github/geekq/workflow-activerecord/coverage)# workflow-activerecord
**ActiveRecord/Rails Integration for the Workflow library**
Major+minor versions of workflow-activerecord are based on the oldest
compatible ActiveRecord API. To use [`workflow`][workflow] with
Rails/ActiveRecord 6.*, 7.* please use:gem 'workflow-activerecord', '~> 6.0'
This will also automatically include the newest compatible version of
the core 'workflow' gem. But you can also choose a specific version:gem 'workflow', '~> 2.0'
gem 'workflow-activerecord', '~> 4.1'Please also have a look at [the sample application][]!
For detailed introduction into workflow DSL please read the
[`workflow` README][workflow]![workflow]: https://github.com/geekq/workflow
[the sample application]: https://github.com/geekq/workflow-rails-sampleState persistence with ActiveRecord
-----------------------------------Workflow library can handle the state persistence fully automatically. You
only need to define a string field on the table called `workflow_state`
and include the workflow mixin in your model class as usual:class Order < ApplicationRecord
include WorkflowActiverecord
workflow do
# list states and transitions here
end
endOn a database record loading all the state check methods e.g.
`article.state`, `article.awaiting_review?` are immediately available.
For new records or if the `workflow_state` field is not set the state
defaults to the first state declared in the workflow specification. In
our example it is `:new`, so `Article.new.new?` returns true and
`Article.new.approved?` returns false.At the end of a successful state transition like `article.approve!` the
new state is immediately saved in the database.You can change this behaviour by overriding `persist_workflow_state`
method.### Scopes
Workflow library also adds automatically generated scopes with names based on
states names:class Order < ApplicationRecord
include WorkflowActiverecord
workflow do
state :approved
state :pending
end
end# returns all orders with `approved` state
Order.with_approved_state# returns all orders with `pending` state
Order.with_pending_state### Custom workflow database column
[meuble](http://imeuble.info/) contributed a solution for using
custom persistence column easily, e.g. for a legacy database schema:class LegacyOrder < ApplicationRecord
include WorkflowActiverecordworkflow_column :foo_bar # use this legacy database column for
# persistence
end### Single table inheritance
Single table inheritance is also supported. Descendant classes can either
inherit the workflow definition from the parent or override with its own
definition.Custom Versions of Existing Adapters
------------------------------------Other adapters (such as a custom ActiveRecord plugin) can be selected by adding a `workflow_adapter` class method, eg.
```ruby
class Example < ApplicationRecord
def self.workflow_adapter
MyCustomAdapter
end
include Workflow# ...
end
```(The above will include `MyCustomAdapter` *instead* of the default
`WorkflowActiverecord` adapter.)Multiple Workflows
------------------I am frequently asked if it's possible to represent multiple "workflows"
in an ActiveRecord class.The solution depends on your business logic and how you want to
structure your implementation.### Use Single Table Inheritance
One solution can be to do it on the class level and use a class
hierarchy. You can use [single table inheritance][STI] so there is only
single `orders` table in the database. Read more in the chapter "Single
Table Inheritance" of the [ActiveRecord documentation][ActiveRecord].
Then you define your different classes:class Order < ActiveRecord::Base
include WorkflowActiverecord
endclass SmallOrder < Order
workflow do
# workflow definition for small orders goes here
end
endclass BigOrder < Order
workflow do
# workflow for big orders, probably with a longer approval chain
end
end### Individual workflows for objects
Another solution would be to connect different workflows to object
instances via metaclass, e.g.# Load an object from the database
booking = Booking.find(1234)# Now define a workflow - exclusively for this object,
# probably depending on some condition or database field
if # some condition
class << booking
include WorkflowActiverecord
workflow do
state :state1
state :state2
end
end
# if some other condition, use a different workflowYou can also encapsulate this in a class method or even put in some
ActiveRecord callback. Please also have a look at [the full working
example][multiple_workflow_test]!### on_transition
You can have a look at an advanced [`on_transition`][] example in
[this test file][advanced_hooks_and_validation_test].[STI]: http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
[ActiveRecord]: http://api.rubyonrails.org/classes/ActiveRecord/Base.html
[multiple_workflow_test]: https://github.com/geekq/workflow-activerecord/blob/develop/test/multiple_workflows_test.rb
[`on_transition`]: https://github.com/geekq/workflow#on_transition
[advanced_hooks_and_validation_test]: http://github.com/geekq/workflow-activerecord/blob/develop/test/advanced_hooks_and_validation_test.rb### Handling the state transition in a transaction
You might want to perform the state transition in a database transaction,
so that the state is persisted atomically with all the other attributes.
To do so, define a module:```ruby
module TransitionTransaction
def process_event!(name, *, **)
transaction { super(name, *, **) }
end
end
```and then prepend it in your model:
```ruby
class Task
workflow do
...
endprepend TransitionTransaction
end
```Changelog
---------### New in the version 6.0.0
* GH-14 retire Ruby 2.6 and Rails 5.* and older since they have reached end of
live; please use workflow-activerecord 4.1.9, if you still depend on
those versions### New in the version 4.1.9
* GH-13 Switch CI (continuous integration) from travis-CI to GitHub
* Tested Rails 7.0 supportSupport
-------### Reporting bugs
About
-----Author: Vladimir Dobriakov,
Copyright (c) 2010-2024 Vladimir Dobriakov and Contributors
Copyright (c) 2008-2009 Vodafone
Copyright (c) 2007-2008 Ryan Allen, FlashDen Pty Ltd
Based on the work of Ryan Allen and Scott Barron
Licensed under MIT license, see the LICENSE file.