statesman 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -0
  3. data/README.md +14 -11
  4. data/Rakefile +5 -0
  5. data/lib/generators/statesman/{transition_generator.rb → active_record_transition_generator.rb} +4 -3
  6. data/lib/generators/statesman/mongoid_transition_generator.rb +31 -0
  7. data/lib/generators/statesman/templates/{transition_model.rb.erb → active_record_transition_model.rb.erb} +2 -0
  8. data/lib/generators/statesman/templates/mongoid_transition_model.rb.erb +13 -0
  9. data/lib/statesman.rb +7 -3
  10. data/lib/statesman/adapters/active_record.rb +1 -2
  11. data/lib/statesman/adapters/active_record_transition.rb +11 -0
  12. data/lib/statesman/adapters/memory_transition.rb +17 -0
  13. data/lib/statesman/adapters/mongoid.rb +56 -0
  14. data/lib/statesman/adapters/mongoid_transition.rb +10 -0
  15. data/lib/statesman/callback.rb +1 -1
  16. data/lib/statesman/config.rb +1 -6
  17. data/lib/statesman/guard.rb +2 -2
  18. data/lib/statesman/machine.rb +7 -6
  19. data/lib/statesman/version.rb +1 -1
  20. data/spec/spec_helper.rb +6 -2
  21. data/spec/statesman/adapters/active_record_spec.rb +9 -7
  22. data/spec/statesman/adapters/active_record_transition_spec.rb +13 -0
  23. data/spec/statesman/adapters/memory_spec.rb +3 -1
  24. data/spec/statesman/adapters/mongoid_spec.rb +53 -0
  25. data/spec/statesman/adapters/shared_examples.rb +4 -1
  26. data/spec/statesman/config_spec.rb +0 -8
  27. data/spec/statesman/machine_spec.rb +3 -2
  28. data/spec/statesman/transition_spec.rb +3 -3
  29. data/spec/support/active_record.rb +10 -10
  30. data/spec/support/mongoid.rb +26 -0
  31. data/statesman.gemspec +1 -0
  32. metadata +31 -5
  33. data/lib/statesman/transition.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 76cf9c150c6ff65db2ce679c9894d577a97d0d1a
4
- data.tar.gz: 9b5726a9af39ca123b63acea82970286debd2dd2
3
+ metadata.gz: d60f1115392a3fb65d3911e82fb0afbda37fa632
4
+ data.tar.gz: 09691527947f5a9b5b788191a84beb6503c1d175
5
5
  SHA512:
6
- metadata.gz: 23f5b5f680675e7b58f573295c9fc30aa00a150df0190afcbd0392b4b56cf0ebe90cef0405f07dc30b9d9c7ab574f5533e88a382d4d5548486906252356620f3
7
- data.tar.gz: 6869fd521815f23be8e74575e57c83dba70b5b4c5d036c2d0ba0321463c2e27ff6dd46f13f4e524f9e18219b80f95623aab50089a5194a36b901723b5eb65426
6
+ metadata.gz: 9a3c0edea7bf34a8eccd9106cb916f85599b7afff8b0e8ad781972ac38535e1a325659be2f71a91332323790309cf0103e3034ccc97d43a2d88b416da882a42d
7
+ data.tar.gz: f53ba2aea159a9e372a26d8b803459317370082631b4070369ba5e8f8e87315fdd0a8a7117db331d509a2635753651123eb667285b5628025b377992457f8248
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 2.0.0
3
+ services: mongodb
4
+ script:
5
+ - bundle exec rubocop
6
+ - bundle exec rake
data/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  A statesmanlike state machine library for Ruby 2.0.
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/statesman.png)](http://badge.fury.io/rb/statesman)
6
+ [![Build Status](https://travis-ci.org/gocardless/statesman.png?branch=master)](https://travis-ci.org/gocardless/statesman)
7
+ [![Code Climate](https://codeclimate.com/github/gocardless/statesman.png)](https://codeclimate.com/github/gocardless/statesman)
8
+
5
9
  Statesman is a little different from other state machine libraries which tack state behaviour directly onto a model. A statesman state machine is defined as a separate class which is instantiated with the model to which it should apply. State transitions are also modelled as a class which can optionally be persisted to the database for a full audit history, including JSON metadata which can be set during a transition.
6
10
 
7
11
  This data model allows for interesting things like using a different state machine depending on the value of a model attribute.
@@ -51,6 +55,8 @@ class Order < ActiveRecord::Base
51
55
  end
52
56
 
53
57
  class OrderTransition < ActiveRecord::Base
58
+ include Statesman::Adapters::ActiveRecordTransition
59
+
54
60
  belongs_to :order, inverse_of: :order_transitions
55
61
  end
56
62
 
@@ -78,14 +84,13 @@ ActiveRecord within Rails:
78
84
  ```ruby
79
85
  Statesman.configure do
80
86
  storage_adapter(Statesman::Adapters::ActiveRecord)
81
- transition_class(OrderTransition)
82
87
  end
83
88
  ```
84
89
 
85
90
  Generate the transition model:
86
91
 
87
92
  ```bash
88
- $ rails g statesman:transition Order OrderTransition
93
+ $ rails g statesman:active_record_transition Order OrderTransition
89
94
  ```
90
95
 
91
96
  And add an association from the parent model:
@@ -114,17 +119,11 @@ end
114
119
  ```ruby
115
120
  Statesman.configure do
116
121
  storage_adapter(Statesman::Adapters::ActiveRecord)
122
+ # ...or
123
+ storage_adapter(Statesman::Adapters::Mongoid)
117
124
  end
118
125
  ```
119
- Statesman defaults to storing transitions in memory. If you're using rails, you can instead configure it to persist transitions to the database by using the ActiveRecord adapter.
120
-
121
- #### `transition_class`
122
- ```ruby
123
- Statesman.configure do
124
- transition_class(OrderTransition)
125
- end
126
- ```
127
- Configure the transition model. For now that means serializing metadata to JSON.
126
+ Statesman defaults to storing transitions in memory. If you're using rails, you can instead configure it to persist transitions to the database by using the ActiveRecord or Mongoid adapter.
128
127
 
129
128
 
130
129
  ## Class methods
@@ -191,3 +190,7 @@ Transition to the passed state, returning `true` on success. Raises `Statesman::
191
190
 
192
191
  #### `Machine#transition_to(:state)`
193
192
  Transition to the passed state, returning `true` on success. Swallows all exceptions and returns false on failure.
193
+
194
+ ---
195
+
196
+ GoCardless ♥ open source. If you do too, come [join us](https://gocardless.com/jobs/backend_developer).
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -1,8 +1,9 @@
1
1
  require "rails/generators"
2
2
 
3
3
  module Statesman
4
- class TransitionGenerator < Rails::Generators::Base
5
- desc "Create a transition model with the required attributes"
4
+ class ActiveRecordTransitionGenerator < Rails::Generators::Base
5
+ desc "Create an ActiveRecord-based transition model" +
6
+ "with the required attributes"
6
7
 
7
8
  argument :parent, type: :string, desc: "Your parent model name"
8
9
  argument :klass, type: :string, desc: "Your transition model name"
@@ -11,7 +12,7 @@ module Statesman
11
12
 
12
13
  def create_model_file
13
14
  template("create_migration.rb.erb", migration_file_name)
14
- template("transition_model.rb.erb", model_file_name)
15
+ template("active_record_transition_model.rb.erb", model_file_name)
15
16
  end
16
17
 
17
18
  private
@@ -0,0 +1,31 @@
1
+ require "rails/generators"
2
+
3
+ module Statesman
4
+ class MongoidTransitionGenerator < Rails::Generators::Base
5
+ desc "Create a Mongoid-based transition model with the required attributes"
6
+
7
+ argument :parent, type: :string, desc: "Your parent model name"
8
+ argument :klass, type: :string, desc: "Your transition model name"
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ def create_model_file
13
+ template("mongoid_transition_model.rb.erb", model_file_name)
14
+ end
15
+
16
+ private
17
+
18
+ def model_file_name
19
+ "app/models/#{klass.underscore}.rb"
20
+ end
21
+
22
+ def collection_name
23
+ klass.underscore.pluralize
24
+ end
25
+
26
+ def parent_id
27
+ parent.underscore + "_id"
28
+ end
29
+
30
+ end
31
+ end
@@ -1,4 +1,6 @@
1
1
  class <%= klass %> < ActiveRecord::Base
2
+ include Statesman::Adapters::ActiveRecordTransition
3
+
2
4
  attr_accessible :to_state, :metadata, :sort_key
3
5
  belongs_to :<%= parent.underscore %>, inverse_of: :<%= table_name %>
4
6
  end
@@ -0,0 +1,13 @@
1
+ class <%= klass %>
2
+ include Mongoid::Document
3
+ include Statesman::Adapters::MongoidTransition
4
+
5
+ field :to_state, type: String
6
+ field :sort_key, type: Integer
7
+ field :statesman_metadata, type: Hash
8
+
9
+ index({ sort_key: 1 })
10
+
11
+ belongs_to :<%= parent.underscore %>, index: true
12
+
13
+ end
data/lib/statesman.rb CHANGED
@@ -3,10 +3,14 @@ module Statesman
3
3
  autoload :Machine, 'statesman/machine'
4
4
  autoload :Callback, 'statesman/callback'
5
5
  autoload :Guard, 'statesman/guard'
6
- autoload :Transition, 'statesman/transition'
7
6
  autoload :Version, 'statesman/version'
8
- require "statesman/adapters/memory"
9
- require "statesman/adapters/active_record"
7
+ module Adapters
8
+ autoload :Memory, "statesman/adapters/memory"
9
+ autoload :ActiveRecord, "statesman/adapters/active_record"
10
+ autoload :ActiveRecordTransition,
11
+ "statesman/adapters/active_record_transition"
12
+ autoload :Mongoid, "statesman/adapters/mongoid"
13
+ end
10
14
 
11
15
  # Example:
12
16
  # Statesman.configure do
@@ -1,5 +1,4 @@
1
- require "active_record"
2
- require "statesman/exceptions"
1
+ require_relative "../exceptions"
3
2
 
4
3
  module Statesman
5
4
  module Adapters
@@ -0,0 +1,11 @@
1
+ require "json"
2
+
3
+ module Statesman
4
+ module Adapters
5
+ module ActiveRecordTransition
6
+ def self.included(base)
7
+ base.send(:serialize, :metadata, JSON)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Statesman
2
+ module Adapters
3
+ class MemoryTransition
4
+ attr_accessor :created_at
5
+ attr_accessor :to_state
6
+ attr_accessor :sort_key
7
+ attr_accessor :metadata
8
+
9
+ def initialize(to, sort_key, metadata = nil)
10
+ @created_at = Time.now
11
+ @to_state = to
12
+ @sort_key = sort_key
13
+ @metadata = metadata
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,56 @@
1
+ require_relative "../exceptions"
2
+
3
+ module Statesman
4
+ module Adapters
5
+ class Mongoid
6
+ attr_reader :transition_class
7
+ attr_reader :parent_model
8
+
9
+ def initialize(transition_class, parent_model)
10
+ @transition_class = transition_class
11
+ @parent_model = parent_model
12
+ unless transition_class_hash_fields.include?('statesman_metadata')
13
+ raise UnserializedMetadataError, metadata_field_error_message
14
+ end
15
+ end
16
+
17
+ def create(to, before_cbs, after_cbs, metadata = {})
18
+ transition = transitions_for_parent.build(to_state: to,
19
+ sort_key: next_sort_key,
20
+ statesman_metadata: metadata)
21
+
22
+ before_cbs.each { |cb| cb.call(@parent_model, transition) }
23
+ transition.save!
24
+ after_cbs.each { |cb| cb.call(@parent_model, transition) }
25
+ @last_transition = nil
26
+ transition
27
+ end
28
+
29
+ def history
30
+ transitions_for_parent.asc(:sort_key)
31
+ end
32
+
33
+ def last
34
+ @last_transition ||= history.last
35
+ end
36
+
37
+ private
38
+
39
+ def transition_class_hash_fields
40
+ transition_class.fields.select { |k, v| v.type == Hash }.keys
41
+ end
42
+
43
+ def metadata_field_error_message
44
+ "#{transition_class.name}#statesman_metadata is not of type 'Hash'"
45
+ end
46
+
47
+ def transitions_for_parent
48
+ @parent_model.send(@transition_class.collection_name)
49
+ end
50
+
51
+ def next_sort_key
52
+ (last && last.sort_key + 10) || 0
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,10 @@
1
+ module Statesman
2
+ module Adapters
3
+ module MongoidTransition
4
+ def self.included(base)
5
+ base.send(:alias_method, :metadata, :statesman_metadata)
6
+ base.send(:alias_method, :metadata=, :statesman_metadata=)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,4 +1,4 @@
1
- require "statesman/exceptions"
1
+ require_relative "exceptions"
2
2
 
3
3
  module Statesman
4
4
  class Callback
@@ -1,5 +1,5 @@
1
1
  require "json"
2
- require "statesman/exceptions"
2
+ require_relative "exceptions"
3
3
 
4
4
  module Statesman
5
5
  class Config
@@ -14,10 +14,5 @@ module Statesman
14
14
  @adapter_class = adapter_class
15
15
  end
16
16
  # rubocop:enable TrivialAccessors
17
-
18
- def transition_class(*args)
19
- args.each { |klass| klass.serialize(:metadata, JSON) }
20
- end
21
-
22
17
  end
23
18
  end
@@ -1,5 +1,5 @@
1
- require "statesman/callback"
2
- require "statesman/exceptions"
1
+ require_relative "callback"
2
+ require_relative "exceptions"
3
3
 
4
4
  module Statesman
5
5
  class Guard < Callback
@@ -1,8 +1,8 @@
1
- require "statesman/version"
2
- require "statesman/exceptions"
3
- require "statesman/guard"
4
- require "statesman/callback"
5
- require "statesman/transition"
1
+ require_relative "version"
2
+ require_relative "exceptions"
3
+ require_relative "guard"
4
+ require_relative "callback"
5
+ require_relative "adapters/memory_transition"
6
6
 
7
7
  module Statesman
8
8
  # The main module, that should be `extend`ed in to state machine classes.
@@ -138,7 +138,8 @@ module Statesman
138
138
  end
139
139
  end
140
140
 
141
- def initialize(object, transition_class: Statesman::Transition)
141
+ def initialize(object,
142
+ transition_class: Statesman::Adapters::MemoryTransition)
142
143
  @object = object
143
144
  @storage_adapter = Statesman.storage_adapter.new(transition_class,
144
145
  object)
@@ -1,3 +1,3 @@
1
1
  module Statesman
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -21,11 +21,15 @@ RSpec.configure do |config|
21
21
  end
22
22
 
23
23
  def prepare_model_table
24
- silence_stream(STDOUT) { CreateMyModelMigration.migrate(:up) }
24
+ silence_stream(STDOUT) do
25
+ CreateMyActiveRecordModelMigration.migrate(:up)
26
+ end
25
27
  end
26
28
 
27
29
  def prepare_transitions_table
28
- silence_stream(STDOUT) { CreateMyModelTransitionMigration.migrate(:up) }
30
+ silence_stream(STDOUT) do
31
+ CreateMyActiveRecordModelTransitionMigration.migrate(:up)
32
+ end
29
33
  end
30
34
  end
31
35
 
@@ -8,25 +8,26 @@ describe Statesman::Adapters::ActiveRecord do
8
8
  prepare_transitions_table
9
9
  end
10
10
 
11
- before { MyModelTransition.serialize(:metadata, JSON) }
11
+ before { MyActiveRecordModelTransition.serialize(:metadata, JSON) }
12
12
 
13
- let(:model) { MyModel.create(current_state: :pending) }
14
- it_behaves_like "an adapter", described_class, MyModelTransition
13
+ let(:model) { MyActiveRecordModel.create(current_state: :pending) }
14
+ it_behaves_like "an adapter", described_class, MyActiveRecordModelTransition
15
15
 
16
16
  describe "#initialize" do
17
17
  context "with unserialized metadata" do
18
- before { MyModelTransition.stub(serialized_attributes: {}) }
18
+ before { MyActiveRecordModelTransition.stub(serialized_attributes: {}) }
19
19
 
20
20
  it "raises an exception if metadata is not serialized" do
21
21
  expect do
22
- described_class.new(MyModelTransition, MyModel)
22
+ described_class.new(MyActiveRecordModelTransition,
23
+ MyActiveRecordModel)
23
24
  end.to raise_exception(Statesman::UnserializedMetadataError)
24
25
  end
25
26
  end
26
27
  end
27
28
 
28
29
  describe "#last" do
29
- let(:adapter) { described_class.new(MyModelTransition, model) }
30
+ let(:adapter) { described_class.new(MyActiveRecordModelTransition, model) }
30
31
 
31
32
  context "with a previously looked up transition" do
32
33
  before do
@@ -35,7 +36,8 @@ describe Statesman::Adapters::ActiveRecord do
35
36
  end
36
37
 
37
38
  it "caches the transition" do
38
- MyModel.any_instance.should_receive(:my_model_transitions).never
39
+ MyActiveRecordModel.any_instance
40
+ .should_receive(:my_active_record_model_transitions).never
39
41
  adapter.last
40
42
  end
41
43
 
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe Statesman::Adapters::ActiveRecordTransition do
5
+ let(:transition_class) { Class.new }
6
+
7
+ describe "including behaviour" do
8
+ it "calls Class.serialize" do
9
+ transition_class.should_receive(:serialize).with(:metadata, JSON).once
10
+ transition_class.send(:include, described_class)
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,9 @@
1
1
  require "spec_helper"
2
2
  require "statesman/adapters/shared_examples"
3
+ require "statesman/adapters/memory_transition"
3
4
 
4
5
  describe Statesman::Adapters::Memory do
5
6
  let(:model) { Class.new { attr_accessor :current_state }.new }
6
- it_behaves_like "an adapter", described_class, Statesman::Transition
7
+ it_behaves_like "an adapter", described_class,
8
+ Statesman::Adapters::MemoryTransition
7
9
  end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+ require "statesman/adapters/shared_examples"
3
+ require "statesman/exceptions"
4
+ require "support/mongoid"
5
+ require "mongoid"
6
+
7
+ describe Statesman::Adapters::Mongoid do
8
+
9
+ after do
10
+ Mongoid.purge!
11
+ end
12
+
13
+ let(:model) { MyMongoidModel.create(current_state: :pending) }
14
+ it_behaves_like "an adapter", described_class, MyMongoidModelTransition
15
+
16
+ describe "#initialize" do
17
+ context "with unserialized metadata" do
18
+ before do
19
+ described_class.any_instance.stub(transition_class_hash_fields: [])
20
+ end
21
+
22
+ it "raises an exception if metadata is not serialized" do
23
+ expect do
24
+ described_class.new(MyMongoidModelTransition, MyMongoidModel)
25
+ end.to raise_exception(Statesman::UnserializedMetadataError)
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "#last" do
31
+ let(:adapter) { described_class.new(MyMongoidModelTransition, model) }
32
+
33
+ context "with a previously looked up transition" do
34
+ before do
35
+ adapter.create(:y, [], [])
36
+ adapter.last
37
+ end
38
+
39
+ it "caches the transition" do
40
+ MyMongoidModel.any_instance
41
+ .should_receive(:my_mongoid_model_transitions).never
42
+ adapter.last
43
+ end
44
+
45
+ context "and a new transition" do
46
+ before { adapter.create(:z, [], []) }
47
+ it "retrieves the new transition from the database" do
48
+ expect(adapter.last.to_state).to eq("z")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -33,7 +33,10 @@ shared_examples_for "an adapter" do |adapter_class, transition_class|
33
33
  context "the new transition" do
34
34
  subject { create }
35
35
  it { should be_a(transition_class) }
36
- its(:to_state) { should be(to) }
36
+
37
+ it "should have the initial state" do
38
+ expect(subject.to_state.to_sym).to eq(to)
39
+ end
37
40
 
38
41
  context "with no previous transition" do
39
42
  its(:sort_key) { should be(0) }
@@ -23,12 +23,4 @@ describe Statesman::Config do
23
23
  expect(defined_adapter).to be(new_adapter)
24
24
  end
25
25
  end
26
-
27
- describe "#transition_class" do
28
- it "serializes metadata to JSON" do
29
- klass = Class.new
30
- klass.should_receive(:serialize).once.with(:metadata, JSON)
31
- Statesman.configure { transition_class(klass) }
32
- end
33
- end
34
26
  end
@@ -194,7 +194,7 @@ describe Statesman::Machine do
194
194
  context "transition class" do
195
195
  it "sets a default" do
196
196
  Statesman.storage_adapter.should_receive(:new).once
197
- .with(Statesman::Transition, my_model)
197
+ .with(Statesman::Adapters::MemoryTransition, my_model)
198
198
  machine.new(my_model)
199
199
  end
200
200
 
@@ -314,7 +314,8 @@ describe Statesman::Machine do
314
314
  instance.transition_to!(:y)
315
315
  end.to change(instance.history, :count).by(1)
316
316
 
317
- expect(instance.history.first).to be_a(Statesman::Transition)
317
+ expect(instance.history.first)
318
+ .to be_a(Statesman::Adapters::MemoryTransition)
318
319
  expect(instance.history.first.to_state).to eq("y")
319
320
  end
320
321
 
@@ -1,10 +1,10 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Statesman::Transition do
3
+ describe Statesman::Adapters::MemoryTransition do
4
4
  describe "#initialize" do
5
5
  let(:to) { :y }
6
6
  let(:sort_key) { 0 }
7
- let(:create) { Statesman::Transition.new(to, sort_key) }
7
+ let(:create) { described_class.new(to, sort_key) }
8
8
 
9
9
  specify { expect(create.to_state).to equal(to) }
10
10
  specify { expect(create.created_at).to be_a(Time) }
@@ -12,7 +12,7 @@ describe Statesman::Transition do
12
12
 
13
13
  context "with metadata passed" do
14
14
  let(:metadata) { { some: :hash } }
15
- let(:create) { Statesman::Transition.new(to, sort_key, metadata) }
15
+ let(:create) { described_class.new(to, sort_key, metadata) }
16
16
 
17
17
  specify { expect(create.metadata).to eq(metadata) }
18
18
  end
@@ -2,17 +2,17 @@ require "support/active_record"
2
2
 
3
3
  DB = Pathname.new("test.sqlite3")
4
4
 
5
- class MyModel < ActiveRecord::Base
6
- has_many :my_model_transitions
5
+ class MyActiveRecordModel < ActiveRecord::Base
6
+ has_many :my_active_record_model_transitions
7
7
  end
8
8
 
9
- class MyModelTransition < ActiveRecord::Base
10
- belongs_to :my_model
9
+ class MyActiveRecordModelTransition < ActiveRecord::Base
10
+ belongs_to :my_active_record_model
11
11
  end
12
12
 
13
- class CreateMyModelMigration < ActiveRecord::Migration
13
+ class CreateMyActiveRecordModelMigration < ActiveRecord::Migration
14
14
  def change
15
- create_table :my_models do |t|
15
+ create_table :my_active_record_models do |t|
16
16
  t.string :current_state
17
17
  t.timestamps
18
18
  end
@@ -20,16 +20,16 @@ class CreateMyModelMigration < ActiveRecord::Migration
20
20
  end
21
21
 
22
22
  # TODO: make this a module we can extend from the app? Or a generator?
23
- class CreateMyModelTransitionMigration < ActiveRecord::Migration
23
+ class CreateMyActiveRecordModelTransitionMigration < ActiveRecord::Migration
24
24
  def change
25
- create_table :my_model_transitions do |t|
25
+ create_table :my_active_record_model_transitions do |t|
26
26
  t.string :to_state
27
- t.integer :my_model_id
27
+ t.integer :my_active_record_model_id
28
28
  t.integer :sort_key
29
29
  t.text :metadata
30
30
  t.timestamps
31
31
  end
32
32
 
33
- add_index :my_model_transitions, :sort_key, unique: true
33
+ add_index :my_active_record_model_transitions, :sort_key, unique: true
34
34
  end
35
35
  end
@@ -0,0 +1,26 @@
1
+ require 'mongoid'
2
+
3
+ Mongoid.configure do |config|
4
+ config.connect_to('statesman_test')
5
+ end
6
+
7
+ class MyMongoidModel
8
+ include Mongoid::Document
9
+
10
+ has_many :my_mongoid_model_transitions
11
+ end
12
+
13
+ class MyMongoidModelTransition
14
+ include Mongoid::Document
15
+
16
+ field :to_state, type: String
17
+ field :sort_key, type: Integer
18
+ field :statesman_metadata, type: Hash
19
+
20
+ index({ sort_key: 1 })
21
+
22
+ belongs_to :my_mongoid_model, index: true
23
+
24
+ alias_method :metadata, :statesman_metadata
25
+ alias_method :metadata=, :statesman_metadata=
26
+ end
data/statesman.gemspec CHANGED
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "guard-rubocop", "~> 0.2.2"
27
27
  spec.add_development_dependency "activerecord", "~> 3.2"
28
28
  spec.add_development_dependency "sqlite3", "~> 1.3.8"
29
+ spec.add_development_dependency "mongoid", "~> 3.1.5"
29
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statesman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harry Marr
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-28 00:00:00.000000000 Z
12
+ date: 2013-11-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -123,6 +123,20 @@ dependencies:
123
123
  - - ~>
124
124
  - !ruby/object:Gem::Version
125
125
  version: 1.3.8
126
+ - !ruby/object:Gem::Dependency
127
+ name: mongoid
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ~>
131
+ - !ruby/object:Gem::Version
132
+ version: 3.1.5
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ~>
138
+ - !ruby/object:Gem::Version
139
+ version: 3.1.5
126
140
  description: A statesmanlike state machine library
127
141
  email:
128
142
  - developers@gocardless.com
@@ -132,30 +146,38 @@ extra_rdoc_files: []
132
146
  files:
133
147
  - .gitignore
134
148
  - .rubocop.yml
149
+ - .travis.yml
135
150
  - Gemfile
136
151
  - Guardfile
137
152
  - LICENSE.txt
138
153
  - README.md
139
154
  - Rakefile
140
155
  - circle.yml
156
+ - lib/generators/statesman/active_record_transition_generator.rb
141
157
  - lib/generators/statesman/migration_generator.rb
158
+ - lib/generators/statesman/mongoid_transition_generator.rb
159
+ - lib/generators/statesman/templates/active_record_transition_model.rb.erb
142
160
  - lib/generators/statesman/templates/create_migration.rb.erb
143
- - lib/generators/statesman/templates/transition_model.rb.erb
161
+ - lib/generators/statesman/templates/mongoid_transition_model.rb.erb
144
162
  - lib/generators/statesman/templates/update_migration.rb.erb
145
- - lib/generators/statesman/transition_generator.rb
146
163
  - lib/statesman.rb
147
164
  - lib/statesman/adapters/active_record.rb
165
+ - lib/statesman/adapters/active_record_transition.rb
148
166
  - lib/statesman/adapters/memory.rb
167
+ - lib/statesman/adapters/memory_transition.rb
168
+ - lib/statesman/adapters/mongoid.rb
169
+ - lib/statesman/adapters/mongoid_transition.rb
149
170
  - lib/statesman/callback.rb
150
171
  - lib/statesman/config.rb
151
172
  - lib/statesman/exceptions.rb
152
173
  - lib/statesman/guard.rb
153
174
  - lib/statesman/machine.rb
154
- - lib/statesman/transition.rb
155
175
  - lib/statesman/version.rb
156
176
  - spec/spec_helper.rb
157
177
  - spec/statesman/adapters/active_record_spec.rb
178
+ - spec/statesman/adapters/active_record_transition_spec.rb
158
179
  - spec/statesman/adapters/memory_spec.rb
180
+ - spec/statesman/adapters/mongoid_spec.rb
159
181
  - spec/statesman/adapters/shared_examples.rb
160
182
  - spec/statesman/callback_spec.rb
161
183
  - spec/statesman/config_spec.rb
@@ -163,6 +185,7 @@ files:
163
185
  - spec/statesman/machine_spec.rb
164
186
  - spec/statesman/transition_spec.rb
165
187
  - spec/support/active_record.rb
188
+ - spec/support/mongoid.rb
166
189
  - statesman.gemspec
167
190
  homepage: https://github.com/gocardless/statesman
168
191
  licenses:
@@ -191,7 +214,9 @@ summary: A statesmanlike state machine library
191
214
  test_files:
192
215
  - spec/spec_helper.rb
193
216
  - spec/statesman/adapters/active_record_spec.rb
217
+ - spec/statesman/adapters/active_record_transition_spec.rb
194
218
  - spec/statesman/adapters/memory_spec.rb
219
+ - spec/statesman/adapters/mongoid_spec.rb
195
220
  - spec/statesman/adapters/shared_examples.rb
196
221
  - spec/statesman/callback_spec.rb
197
222
  - spec/statesman/config_spec.rb
@@ -199,3 +224,4 @@ test_files:
199
224
  - spec/statesman/machine_spec.rb
200
225
  - spec/statesman/transition_spec.rb
201
226
  - spec/support/active_record.rb
227
+ - spec/support/mongoid.rb
@@ -1,15 +0,0 @@
1
- module Statesman
2
- class Transition
3
- attr_accessor :created_at
4
- attr_accessor :to_state
5
- attr_accessor :sort_key
6
- attr_accessor :metadata
7
-
8
- def initialize(to, sort_key, metadata = nil)
9
- @created_at = Time.now
10
- @to_state = to
11
- @sort_key = sort_key
12
- @metadata = metadata
13
- end
14
- end
15
- end