state_machine_history 0.2.1
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.
- data/README.rdoc +70 -0
- data/generators/state_machine_history/state_machine_history_generator.rb +22 -0
- data/generators/state_machine_history/templates/create_machine_history.rb +16 -0
- data/generators/state_machine_history_2/USAGE +7 -0
- data/generators/state_machine_history_2/state_machine_history_2_generator.rb +11 -0
- data/generators/state_machine_history_2/templates/create_machine_history.rb +16 -0
- data/lib/machine_history.rb +5 -0
- data/lib/state_machine_history.rb +64 -0
- metadata +93 -0
data/README.rdoc
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
= state_machine_history
|
2
|
+
state_machine_history is an extension of the state_machine[https://github.com/pluginaweek/state_machine] gem,
|
3
|
+
that logs transitions between states and allows to check if a state was visited earlier.
|
4
|
+
|
5
|
+
== Install
|
6
|
+
gem install state_machine_history
|
7
|
+
|
8
|
+
=== Ruby On Rails 2.x
|
9
|
+
Add the gem dependency to environment.rb:
|
10
|
+
...
|
11
|
+
config.gem 'state_machine_history'
|
12
|
+
...
|
13
|
+
Generate the migration:
|
14
|
+
script/generate state_machine_history_2 create_machine_history
|
15
|
+
Run the migration
|
16
|
+
rake db:migrate
|
17
|
+
|
18
|
+
=== Ruby On Rails 3
|
19
|
+
In Gemfile:
|
20
|
+
gem 'state_machine_history'
|
21
|
+
Generate the migration:
|
22
|
+
rails generate state_machine_history create_machine_history
|
23
|
+
Run the migration:
|
24
|
+
rake db:migrate
|
25
|
+
|
26
|
+
== Usage
|
27
|
+
This gem adds logging function to the state_machine gem.
|
28
|
+
Sample:
|
29
|
+
|
30
|
+
=== Class definition
|
31
|
+
|
32
|
+
class Order
|
33
|
+
state_machine :initial => :not_selected do
|
34
|
+
# Switch on state machine logging
|
35
|
+
track_history
|
36
|
+
|
37
|
+
event :choose do
|
38
|
+
transition :not_selected => :selected
|
39
|
+
end
|
40
|
+
event :add_to_basket do
|
41
|
+
transition :selected => :in_basket
|
42
|
+
end
|
43
|
+
event :pay do
|
44
|
+
transition :in_basket => :paid
|
45
|
+
end
|
46
|
+
event :to_send do
|
47
|
+
transition :paid => :sent
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
=== Using extensions
|
53
|
+
|
54
|
+
order = Order.new
|
55
|
+
# Perform transition (state change is logged)
|
56
|
+
order.choose
|
57
|
+
# Find whether order has visited not_selected state before selected one
|
58
|
+
order.was_there?(:not_selected, :selected) #=> true
|
59
|
+
# Find whether order has visited not_selected state before the current one
|
60
|
+
order.was_there?(:not_selected) #=> true
|
61
|
+
|
62
|
+
== Credits
|
63
|
+
|
64
|
+
=== Project Team
|
65
|
+
* Mykhaylo Sorochan - Project Manager
|
66
|
+
* Dmitriy Landberg - Software Developer
|
67
|
+
* Nataliya Shatokhina - Tester
|
68
|
+
* Sergey Mostovoy - Extension idea
|
69
|
+
|
70
|
+
Copyright (c) 2010 {Sphere Consulting Inc.}[http://www.sphereinc.com], released under the MIT license (see LICENSE).
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
class StateMachineHistoryGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.next_migration_number(dirname)
|
12
|
+
if ActiveRecord::Base.timestamped_migrations
|
13
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
14
|
+
else
|
15
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_migration_file
|
20
|
+
migration_template 'create_machine_history.rb', 'db/migrate/create_machine_history.rb'
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateMachineHistory < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :machine_histories do |t|
|
4
|
+
t.column :loggable_id, :integer
|
5
|
+
t.column :loggable_type, :string
|
6
|
+
t.column :from_state, :string
|
7
|
+
t.column :to_state, :string
|
8
|
+
t.column :event, :string
|
9
|
+
t.column :created_at, :datetime
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :machine_histories
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Description:
|
2
|
+
The state machine history generator creates a migration to add the history table.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
./script/generate state_machine_history_2 create_machine_history
|
6
|
+
|
7
|
+
This will create a migration in db/migrate/. Run "rake db:migrate" to update your database.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateMachineHistory < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :machine_histories do |t|
|
4
|
+
t.column :loggable_id, :integer
|
5
|
+
t.column :loggable_type, :string
|
6
|
+
t.column :from_state, :string
|
7
|
+
t.column :to_state, :string
|
8
|
+
t.column :event, :string
|
9
|
+
t.column :created_at, :datetime
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :machine_histories
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.dirname(__FILE__) + "/../"))
|
2
|
+
require 'lib/machine_history'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'state_machine'
|
5
|
+
|
6
|
+
module StateMachineHistory
|
7
|
+
|
8
|
+
class InvalidState < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.class_eval do
|
13
|
+
|
14
|
+
def track_history
|
15
|
+
self.owner_class.class_eval do
|
16
|
+
has_one :machine_log, :as => :loggable
|
17
|
+
end
|
18
|
+
|
19
|
+
before_transition(any => any) do |object, transition|
|
20
|
+
MachineHistory.create(:loggable => object,
|
21
|
+
:from_state=>transition.from_name.to_s, :to_state=>transition.to_name.to_s,
|
22
|
+
:event=>transition.event.to_s )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :define_event_helpers_original, :define_event_helpers
|
27
|
+
|
28
|
+
def define_event_helpers
|
29
|
+
define_event_helpers_original
|
30
|
+
|
31
|
+
# Define the method which determines whether we visited a state before current or particular one
|
32
|
+
define_instance_method(:was_there?) do |machine, object, from_state, to_state|
|
33
|
+
to_state ||= object.state
|
34
|
+
from_state = from_state.to_s
|
35
|
+
to_state = to_state.to_s
|
36
|
+
|
37
|
+
is_from_state = machine.states.detect {|item| item.name.to_s == from_state}
|
38
|
+
raise InvalidState, "\"#{from_state}\" is an unknown state machine state" unless is_from_state
|
39
|
+
|
40
|
+
is_to_state = machine.states.detect {|item| item.name.to_s == to_state}
|
41
|
+
raise InvalidState, "\"#{to_state}\" is an unknown state machine state" unless is_to_state
|
42
|
+
|
43
|
+
history = MachineHistory.find(:last, :conditions => {:loggable_id => object.id,
|
44
|
+
:to_state => to_state})
|
45
|
+
|
46
|
+
next false if history.nil?
|
47
|
+
|
48
|
+
date = history.created_at
|
49
|
+
is_state = MachineHistory.find(:last,
|
50
|
+
:conditions => ["loggable_id = ? and from_state = ? and created_at <= ?",
|
51
|
+
object.id, from_state, date])
|
52
|
+
|
53
|
+
is_state ? true : false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
class StateMachine::Machine
|
63
|
+
include StateMachineHistory
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: state_machine_history
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Sphere Consulting Inc.
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-17 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: state_machine
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 51
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 9
|
33
|
+
- 4
|
34
|
+
version: 0.9.4
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: " Extensions for the state_machine gem\n"
|
38
|
+
email:
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- generators/state_machine_history/state_machine_history_generator.rb
|
47
|
+
- generators/state_machine_history/templates/create_machine_history.rb
|
48
|
+
- generators/state_machine_history_2/state_machine_history_2_generator.rb
|
49
|
+
- generators/state_machine_history_2/templates/create_machine_history.rb
|
50
|
+
- generators/state_machine_history_2/USAGE
|
51
|
+
- lib/machine_history.rb
|
52
|
+
- lib/state_machine_history.rb
|
53
|
+
- README.rdoc
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: https://github.com/SphereConsultingInc/state_machine_history/
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 57
|
69
|
+
segments:
|
70
|
+
- 1
|
71
|
+
- 8
|
72
|
+
- 7
|
73
|
+
version: 1.8.7
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 23
|
80
|
+
segments:
|
81
|
+
- 1
|
82
|
+
- 3
|
83
|
+
- 6
|
84
|
+
version: 1.3.6
|
85
|
+
requirements: []
|
86
|
+
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 1.3.7
|
89
|
+
signing_key:
|
90
|
+
specification_version: 3
|
91
|
+
summary: Extensions for the state_machine gem
|
92
|
+
test_files: []
|
93
|
+
|