stonepath 0.4.2 → 0.4.3.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +4 -2
- data/Rakefile +4 -3
- data/VERSION +1 -1
- data/lib/stonepath/work_item.rb +3 -1
- data/lib/stonepath.rb +0 -2
- data/rails_generators/stonepath_event_log/stonepath_event_log_generator.rb +9 -0
- data/rails_generators/stonepath_event_log/templates/create_event_records.rb +17 -0
- data/rails_generators/stonepath_event_log/templates/event_record.rb +5 -0
- data/rails_generators/stonepath_task/USAGE +1 -0
- data/rails_generators/stonepath_task/stonepath_task_generator.rb +29 -0
- data/rails_generators/stonepath_task/templates/generic_task.rb +23 -0
- data/rails_generators/stonepath_task/templates/generic_task_migration.rb +36 -0
- data/rails_generators/stonepath_workitem/USAGE +51 -0
- data/rails_generators/stonepath_workitem/stonepath_workitem_generator.rb +196 -0
- data/rails_generators/stonepath_workitem/templates/actions/create.rb +9 -0
- data/rails_generators/stonepath_workitem/templates/actions/destroy.rb +6 -0
- data/rails_generators/stonepath_workitem/templates/actions/edit.rb +3 -0
- data/rails_generators/stonepath_workitem/templates/actions/index.rb +3 -0
- data/rails_generators/stonepath_workitem/templates/actions/new.rb +3 -0
- data/rails_generators/stonepath_workitem/templates/actions/show.rb +3 -0
- data/rails_generators/stonepath_workitem/templates/actions/update.rb +9 -0
- data/rails_generators/stonepath_workitem/templates/controller.rb +3 -0
- data/rails_generators/stonepath_workitem/templates/event_controller.rb +25 -0
- data/rails_generators/stonepath_workitem/templates/fixtures.yml +9 -0
- data/rails_generators/stonepath_workitem/templates/helper.rb +2 -0
- data/rails_generators/stonepath_workitem/templates/migration.rb +24 -0
- data/rails_generators/stonepath_workitem/templates/model.rb +33 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/create.rb +11 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/destroy.rb +6 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/edit.rb +4 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/index.rb +4 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/new.rb +4 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/show.rb +4 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/update.rb +11 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/controller.rb +5 -0
- data/rails_generators/stonepath_workitem/templates/tests/testunit/model.rb +7 -0
- data/rails_generators/stonepath_workitem/templates/views/erb/_form.html.erb +10 -0
- data/rails_generators/stonepath_workitem/templates/views/erb/edit.html.erb +12 -0
- data/rails_generators/stonepath_workitem/templates/views/erb/index.html.erb +27 -0
- data/rails_generators/stonepath_workitem/templates/views/erb/new.html.erb +5 -0
- data/rails_generators/stonepath_workitem/templates/views/erb/show.html.erb +26 -0
- metadata +51 -6
data/README.rdoc
CHANGED
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
State-based workflow for rails.
|
4
4
|
|
5
|
-
|
5
|
+
UPDATE: The StonePath acl is being pulled out into a separate project called StoneWall.
|
6
|
+
Update #2: Rather than reinvent a common wheel, StonePath now relies on the sentient_user gem.
|
6
7
|
|
7
|
-
|
8
|
+
For more information, check out the stonepath.pdf in this same directory. Stonepath is in real use and under active development, so improved docs will be arriving in this location shortly.
|
8
9
|
|
9
10
|
|
11
|
+
gem install stonepath
|
10
12
|
|
11
13
|
== LICENSE:
|
12
14
|
|
data/Rakefile
CHANGED
@@ -13,9 +13,10 @@ begin
|
|
13
13
|
gemspec.homepage = "http://github.com/bokmann/stonepath"
|
14
14
|
gemspec.description = "Stateful workflow modeling for Rails"
|
15
15
|
gemspec.authors = ["David Bock"]
|
16
|
-
gemspec.add_dependency('activerecord','>=
|
17
|
-
gemspec.add_dependency('aasm','>= 2.
|
18
|
-
gemspec.add_dependency('sentient_user','>= 0.
|
16
|
+
gemspec.add_dependency('activerecord','>= 2.0.0')
|
17
|
+
gemspec.add_dependency('aasm','>= 2.1.3')
|
18
|
+
gemspec.add_dependency('sentient_user','>= 0.1.0')
|
19
|
+
|
19
20
|
end
|
20
21
|
|
21
22
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.3.pre
|
data/lib/stonepath/work_item.rb
CHANGED
data/lib/stonepath.rb
CHANGED
@@ -2,8 +2,6 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
4
|
module StonePath
|
5
|
-
require 'stonepath/railtie' if defined?(Rails)
|
6
|
-
|
7
5
|
# main hook into the framework. From here, this should simply have methods that cause other includes to happen.
|
8
6
|
def self.included(base)
|
9
7
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class StonepathEventLogGenerator < Rails::Generator::Base
|
2
|
+
def manifest
|
3
|
+
record do |m|
|
4
|
+
task_name = args[0]
|
5
|
+
m.template('event_record.rb', "app/models/event_record.rb")
|
6
|
+
m.migration_template("create_event_records.rb", "db/migrate", :migration_file_name => "create_event_records")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateEventRecords < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :event_records do |t|
|
4
|
+
|
5
|
+
t.references :auditable, :polymorphic => true
|
6
|
+
t.string :event_name
|
7
|
+
t.string :old_state_name
|
8
|
+
t.string :new_state_name
|
9
|
+
t.integer :user_id #This will rely on the acl controller hack
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :event_records
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Usage goes here.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class StonepathTaskGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
|
4
|
+
attr_accessor :name, :attributes
|
5
|
+
|
6
|
+
def initialize(runtime_args, runtime_options = {})
|
7
|
+
super
|
8
|
+
usage if @args.empty?
|
9
|
+
|
10
|
+
@name = @args.first
|
11
|
+
@controller_actions = []
|
12
|
+
@attributes = []
|
13
|
+
|
14
|
+
@args[1..-1].each do |arg|
|
15
|
+
if arg.include? ':'
|
16
|
+
@attributes << Rails::Generator::GeneratedAttribute.new(*arg.split(":"))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@attributes.uniq!
|
21
|
+
end
|
22
|
+
|
23
|
+
def manifest
|
24
|
+
record do |m|
|
25
|
+
m.template('generic_task.rb', "app/models/#{@name.tableize.singularize}.rb")
|
26
|
+
m.migration_template("generic_task_migration.rb", "db/migrate", :migration_file_name => "create_#{@name.tableize}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class <%= args[0].classify %> < ActiveRecord::Base
|
2
|
+
include StonePath
|
3
|
+
|
4
|
+
stonepath_task
|
5
|
+
|
6
|
+
#logs_transitions # uncomment this if you generate the event log.
|
7
|
+
|
8
|
+
attr_accessible :workitem, :workbench, <%= attributes.map { |a| ":#{a.name}" }.join(", ") %>
|
9
|
+
|
10
|
+
# you might think 'overdue' should be a state, but no, part of the stonepath
|
11
|
+
# methodology is that states should be as free of time definition as possible.
|
12
|
+
# Thinking about it, this should make sense. Think of the conversation:
|
13
|
+
# A: "That isn't done yet?"
|
14
|
+
# B: "No, it's overdue"
|
15
|
+
# A: "Well, where is it then?"
|
16
|
+
# B: "It's still on Mike's desk, in process".
|
17
|
+
#
|
18
|
+
# so the state would be 'in process', even though it is 'overdue'.
|
19
|
+
def overdue?
|
20
|
+
(Time.now > due_at) && !self.completed?
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Create<%= args[0].tableize.classify.pluralize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :<%= args[0].tableize %> do |t|
|
4
|
+
|
5
|
+
# don't change these unless you want to get deep into meta in the
|
6
|
+
# stonepath gem.
|
7
|
+
t.string :aasm_state
|
8
|
+
t.references :workitem, :polymorphic => true
|
9
|
+
t.references :workbench, :polymorphic => true
|
10
|
+
|
11
|
+
t.datetime :due_at
|
12
|
+
t.datetime :completed_at
|
13
|
+
t.timestamps
|
14
|
+
|
15
|
+
# This "urgent at' concept was useful in one of the domains StonePath
|
16
|
+
# was written/extracted from. The idea is thatm while something is 'due'
|
17
|
+
# at a specific time, it might become urgent shortly before it is due.
|
18
|
+
# In that domain, we color-coded tasks as green (due date is far out)
|
19
|
+
# yellow (urgent timestap has passed), and red (overdue - due date
|
20
|
+
# has passed). This won't become part of the framework, but I like the
|
21
|
+
# idea so much I thought I'd comment it here until it gets in some
|
22
|
+
# official documentation for 'advanced usage'.
|
23
|
+
# t.datetime :urgent_at
|
24
|
+
|
25
|
+
# Your attributes should be defined here.
|
26
|
+
<%- for attribute in attributes -%>
|
27
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
28
|
+
<%- end -%>
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.down
|
34
|
+
drop_table :<%= args[0].tableize %>
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
Description:
|
2
|
+
Scaffolds an entire resource, from model and migration to controller and
|
3
|
+
views. The resource is ready to use as a starting point for your restful,
|
4
|
+
resource-oriented application. Tests or specs are also generated depending
|
5
|
+
on if you have a "spec" directory or not.
|
6
|
+
|
7
|
+
IMPORTANT: This generator uses the "title" helper method which is generated
|
8
|
+
by the nifty_layout generator. You may want to run that generator first.
|
9
|
+
|
10
|
+
Usage:
|
11
|
+
Pass the name of the model, either CamelCased or under_scored, as the first
|
12
|
+
argument, and an optional list of attribute pairs and controller actions.
|
13
|
+
|
14
|
+
If no controller actions are specified, they will default to index, show,
|
15
|
+
new, create, edit, update, and destroy.
|
16
|
+
|
17
|
+
IMPORTANT: If no attribute pairs are specified, no model will be generated.
|
18
|
+
It will try to determine the attributes from an existing model.
|
19
|
+
|
20
|
+
Attribute pairs are column_name:sql_type arguments specifying the
|
21
|
+
model's attributes. Timestamps are added by default, so you don't have to
|
22
|
+
specify them by hand as 'created_at:datetime updated_at:datetime'.
|
23
|
+
|
24
|
+
For example, `nifty_scaffold post name:string content:text hidden:boolean`
|
25
|
+
gives you a model with those three attributes, a controller that handles
|
26
|
+
the create/show/update/destroy, forms to create and edit your posts, and
|
27
|
+
an index that lists them all, as well as a map.resources :posts
|
28
|
+
declaration in config/routes.rb.
|
29
|
+
|
30
|
+
Adding an "!" in the mix of arguments will invert the passed controller
|
31
|
+
actions. This will include all 7 controller actitons except the ones
|
32
|
+
mentioned. This option doesn't effect model attributes.
|
33
|
+
|
34
|
+
Examples:
|
35
|
+
script/generate nifty_scaffold post
|
36
|
+
|
37
|
+
Will create a controller called "posts" it will contain all seven
|
38
|
+
CRUD actions along with the views. A model will NOT be created,
|
39
|
+
instead it will look for an existing model and use those attributes.
|
40
|
+
|
41
|
+
script/generate nifty_scaffold post name:string content:text index new edit
|
42
|
+
|
43
|
+
Will create a Post model and migration file with the name and content
|
44
|
+
attributes. It will also create a controller with index, new, create,
|
45
|
+
edit, and update actions. Notice the create and update actions are
|
46
|
+
added automatically with new and edit.
|
47
|
+
|
48
|
+
script/generate nifty_scaffold post ! show new
|
49
|
+
|
50
|
+
Creates a posts controller (no model) with index, edit, update, and
|
51
|
+
destroy actions.
|
@@ -0,0 +1,196 @@
|
|
1
|
+
class StonepathWorkitemGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
load File.expand_path( File.dirname(__FILE__)) + '/../../lib/stonepath/extensions/rails_generator_commands.rb'
|
4
|
+
|
5
|
+
attr_accessor :name, :attributes
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if @args.empty?
|
10
|
+
|
11
|
+
@name = @args.first
|
12
|
+
@attributes = []
|
13
|
+
@args[1..-1].each do |arg|
|
14
|
+
if arg.include? ':'
|
15
|
+
@attributes << Rails::Generator::GeneratedAttribute.new(*arg.split(":"))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
@attributes.uniq!
|
19
|
+
@controller_actions = all_actions
|
20
|
+
end
|
21
|
+
|
22
|
+
def manifest
|
23
|
+
record do |m|
|
24
|
+
|
25
|
+
m.directory "app/models"
|
26
|
+
m.template "model.rb", "app/models/#{singular_name}.rb"
|
27
|
+
m.migration_template "migration.rb", "db/migrate", :migration_file_name => "create_#{plural_name}"
|
28
|
+
m.directory "test/unit"
|
29
|
+
m.template "tests/#{test_framework}/model.rb", "test/unit/#{singular_name}_test.rb"
|
30
|
+
m.directory "test/fixtures"
|
31
|
+
m.template "fixtures.yml", "test/fixtures/#{plural_name}.yml"
|
32
|
+
|
33
|
+
m.directory "app/controllers"
|
34
|
+
m.template "controller.rb", "app/controllers/#{plural_name}_controller.rb"
|
35
|
+
m.template "event_controller.rb", "app/controllers/#{singular_name}_events_controller.rb"
|
36
|
+
|
37
|
+
m.directory "app/helpers"
|
38
|
+
m.template "helper.rb", "app/helpers/#{plural_name}_helper.rb"
|
39
|
+
|
40
|
+
m.directory "app/views/#{plural_name}"
|
41
|
+
@controller_actions.each do |action|
|
42
|
+
if File.exist? source_path("views/#{view_language}/#{action}.html.#{view_language}")
|
43
|
+
m.template "views/#{view_language}/#{action}.html.#{view_language}", "app/views/#{plural_name}/#{action}.html.#{view_language}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if form_partial?
|
48
|
+
m.template "views/#{view_language}/_form.html.#{view_language}", "app/views/#{plural_name}/_form.html.#{view_language}"
|
49
|
+
end
|
50
|
+
|
51
|
+
m.route_stonepath_workitems plural_name
|
52
|
+
|
53
|
+
m.directory "test/functional"
|
54
|
+
m.template "tests/#{test_framework}/controller.rb", "test/functional/#{plural_name}_controller_test.rb"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def form_partial?
|
59
|
+
actions? :new, :edit
|
60
|
+
end
|
61
|
+
|
62
|
+
def all_actions
|
63
|
+
%w[index show new create edit update destroy]
|
64
|
+
end
|
65
|
+
|
66
|
+
def action?(name)
|
67
|
+
@controller_actions.include? name.to_s
|
68
|
+
end
|
69
|
+
|
70
|
+
def actions?(*names)
|
71
|
+
names.all? { |n| action? n.to_s }
|
72
|
+
end
|
73
|
+
|
74
|
+
def singular_name
|
75
|
+
name.underscore
|
76
|
+
end
|
77
|
+
|
78
|
+
def plural_name
|
79
|
+
name.underscore.pluralize
|
80
|
+
end
|
81
|
+
|
82
|
+
def class_name
|
83
|
+
name.camelize
|
84
|
+
end
|
85
|
+
|
86
|
+
def object_id_name
|
87
|
+
(class_name.tableize.singularize + "_id")
|
88
|
+
end
|
89
|
+
|
90
|
+
def plural_class_name
|
91
|
+
plural_name.camelize
|
92
|
+
end
|
93
|
+
|
94
|
+
def controller_methods(dir_name)
|
95
|
+
@controller_actions.map do |action|
|
96
|
+
read_template("#{dir_name}/#{action}.rb")
|
97
|
+
end.join(" \n").strip
|
98
|
+
end
|
99
|
+
|
100
|
+
def render_form
|
101
|
+
if form_partial?
|
102
|
+
if options[:haml]
|
103
|
+
"= render :partial => 'form'"
|
104
|
+
else
|
105
|
+
"<%= render :partial => 'form' %>"
|
106
|
+
end
|
107
|
+
else
|
108
|
+
read_template("views/#{view_language}/_form.html.#{view_language}")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def items_path(suffix = 'path')
|
113
|
+
if action? :index
|
114
|
+
"#{plural_name}_#{suffix}"
|
115
|
+
else
|
116
|
+
"root_#{suffix}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def item_path(suffix = 'path')
|
121
|
+
if action? :show
|
122
|
+
"@#{singular_name}"
|
123
|
+
else
|
124
|
+
items_path(suffix)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def item_path_for_spec(suffix = 'path')
|
129
|
+
if action? :show
|
130
|
+
"#{singular_name}_#{suffix}(assigns[:#{singular_name}])"
|
131
|
+
else
|
132
|
+
items_path(suffix)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def item_path_for_test(suffix = 'path')
|
137
|
+
if action? :show
|
138
|
+
"#{singular_name}_#{suffix}(assigns(:#{singular_name}))"
|
139
|
+
else
|
140
|
+
items_path(suffix)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def model_columns_for_attributes
|
145
|
+
class_name.constantize.columns.reject do |column|
|
146
|
+
column.name.to_s =~ /^(id|created_at|updated_at)$/
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def rspec?
|
151
|
+
test_framework == :rspec
|
152
|
+
end
|
153
|
+
|
154
|
+
protected
|
155
|
+
|
156
|
+
def view_language
|
157
|
+
options[:haml] ? 'haml' : 'erb'
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_framework
|
161
|
+
options[:test_framework] ||= default_test_framework
|
162
|
+
end
|
163
|
+
|
164
|
+
def default_test_framework
|
165
|
+
File.exist?(destination_path("spec")) ? :rspec : :testunit
|
166
|
+
end
|
167
|
+
|
168
|
+
def add_options!(opt)
|
169
|
+
opt.separator ''
|
170
|
+
opt.separator 'Options:'
|
171
|
+
# opt.on("--skip-model", "Don't generate a model or migration file.") { |v| options[:skip_model] = v }
|
172
|
+
# opt.on("--skip-migration", "Don't generate migration file for model.") { |v| options[:skip_migration] = v }
|
173
|
+
# opt.on("--skip-timestamps", "Don't add timestamps to migration file.") { |v| options[:skip_timestamps] = v }
|
174
|
+
# opt.on("--skip-controller", "Don't generate controller, helper, or views.") { |v| options[:skip_controller] = v }
|
175
|
+
# opt.on("--invert", "Generate all controller actions except these mentioned.") { |v| options[:invert] = v }
|
176
|
+
# opt.on("--haml", "Generate HAML views instead of ERB.") { |v| options[:haml] = v }
|
177
|
+
# opt.on("--testunit", "Use test/unit for test files.") { options[:test_framework] = :testunit }
|
178
|
+
# opt.on("--rspec", "Use RSpec for test files.") { options[:test_framework] = :rspec }
|
179
|
+
# opt.on("--shoulda", "Use Shoulda for test files.") { options[:test_framework] = :shoulda }
|
180
|
+
end
|
181
|
+
|
182
|
+
# is there a better way to do this? Perhaps with const_defined?
|
183
|
+
def model_exists?
|
184
|
+
File.exist? destination_path("app/models/#{singular_name}.rb")
|
185
|
+
end
|
186
|
+
|
187
|
+
def read_template(relative_path)
|
188
|
+
ERB.new(File.read(source_path(relative_path)), nil, '-').result(binding)
|
189
|
+
end
|
190
|
+
|
191
|
+
def banner
|
192
|
+
<<-EOS
|
193
|
+
Creates a WorkItem as defined by the Stonepath Workflow Methodology
|
194
|
+
EOS
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
def create
|
2
|
+
@<%= singular_name %> = <%= class_name %>.new(params[:<%= singular_name %>])
|
3
|
+
if @<%= singular_name %>.save
|
4
|
+
flash[:notice] = "Successfully created <%= name.underscore.humanize.downcase %>."
|
5
|
+
redirect_to <%= item_path('url') %>
|
6
|
+
else
|
7
|
+
render :action => 'new'
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
def update
|
2
|
+
@<%= singular_name %> = <%= class_name %>.find(params[:id])
|
3
|
+
if @<%= singular_name %>.update_attributes(params[:<%= singular_name %>])
|
4
|
+
flash[:notice] = "Successfully updated <%= name.underscore.humanize.downcase %>."
|
5
|
+
redirect_to <%= item_path('url') %>
|
6
|
+
else
|
7
|
+
render :action => 'edit'
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# this is now your file to do with as you see fit. Before you modify it though, make sure you
|
2
|
+
# understand how the nested restful routes are defined in the routes.rb file!
|
3
|
+
|
4
|
+
class <%= class_name %>EventsController < ApplicationController
|
5
|
+
|
6
|
+
def create
|
7
|
+
if request.post?
|
8
|
+
@object = <%= class_name %>.find(params[:<%= object_id_name %>])
|
9
|
+
event = params[:id]
|
10
|
+
if <%= class_name %>.aasm_events.keys.include?(event.to_sym)
|
11
|
+
respond_to do |format|
|
12
|
+
if @object.send(event + "!")
|
13
|
+
flash[:notice] = "Event '#{event}' was successfully performed."
|
14
|
+
format.html { redirect_to(@object) }
|
15
|
+
format.xml { render :xml => @object }
|
16
|
+
else
|
17
|
+
flash[:notice] = "Event '#{event}' was NOT successfully performed."
|
18
|
+
format.html { redirect_to(@object) }
|
19
|
+
format.xml { render :xml => @object.errors, :status => :unprocessable_entity }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Create<%= plural_class_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :<%= plural_name %> do |t|
|
4
|
+
# These are the attributes of a workitem
|
5
|
+
t.string :aasm_state
|
6
|
+
t.integer :owner_id
|
7
|
+
|
8
|
+
# Your attributes should be defined here.
|
9
|
+
<%- for attribute in attributes -%>
|
10
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
11
|
+
<%- end -%>
|
12
|
+
<%- unless options[:skip_timestamps] -%>
|
13
|
+
t.timestamps
|
14
|
+
<%- end -%>
|
15
|
+
end
|
16
|
+
|
17
|
+
#I'd like to create an index on aasm_state here.
|
18
|
+
# you might optionally want to index owner_id
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.down
|
22
|
+
drop_table :<%= plural_name %>
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class <%= class_name %> < ActiveRecord::Base
|
2
|
+
include StonePath
|
3
|
+
|
4
|
+
stonepath_workitem do
|
5
|
+
#owned_by :your_owning class
|
6
|
+
|
7
|
+
#tasked_through :your_implementation_of_stonepath_task
|
8
|
+
|
9
|
+
# This is an example trivial workflow. This is now yours to change as
|
10
|
+
# you see fit.
|
11
|
+
aasm_initial_state :pending
|
12
|
+
|
13
|
+
aasm_state :pending
|
14
|
+
aasm_state :in_process
|
15
|
+
aasm_state :completed
|
16
|
+
|
17
|
+
aasm_event :activate do
|
18
|
+
transitions :to => :in_process, :from => :pending
|
19
|
+
end
|
20
|
+
|
21
|
+
aasm_event :complete do
|
22
|
+
transitions :to => :completed, :from => :in_process
|
23
|
+
end
|
24
|
+
|
25
|
+
aasm_event :reactivate do
|
26
|
+
transitions :to => :in_process, :from => :completed
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_accessible <%= attributes.map { |a| ":#{a.name}" }.join(", ") %>
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
def test_create_invalid
|
2
|
+
<%= class_name %>.any_instance.stubs(:valid?).returns(false)
|
3
|
+
post :create
|
4
|
+
assert_template 'new'
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_create_valid
|
8
|
+
<%= class_name %>.any_instance.stubs(:valid?).returns(true)
|
9
|
+
post :create
|
10
|
+
assert_redirected_to <%= item_path_for_test('url') %>
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
def test_update_invalid
|
2
|
+
<%= class_name %>.any_instance.stubs(:valid?).returns(false)
|
3
|
+
put :update, :id => <%= class_name %>.first
|
4
|
+
assert_template 'edit'
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_update_valid
|
8
|
+
<%= class_name %>.any_instance.stubs(:valid?).returns(true)
|
9
|
+
put :update, :id => <%= class_name %>.first
|
10
|
+
assert_redirected_to <%= item_path_for_test('url') %>
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%% form_for @<%= singular_name %> do |f| %>
|
2
|
+
<%%= f.error_messages %>
|
3
|
+
<%- for attribute in attributes -%>
|
4
|
+
<p>
|
5
|
+
<%%= f.label :<%= attribute.name %> %><br />
|
6
|
+
<%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
|
7
|
+
</p>
|
8
|
+
<%- end -%>
|
9
|
+
<p><%%= f.submit "Submit" %></p>
|
10
|
+
<%% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= render_form %>
|
2
|
+
|
3
|
+
<%- if actions? :show, :index -%>
|
4
|
+
<p>
|
5
|
+
<%- if action? :show -%>
|
6
|
+
<%%= link_to "Show", @<%= singular_name %> %> |
|
7
|
+
<%- end -%>
|
8
|
+
<%- if action? :index -%>
|
9
|
+
<%%= link_to "View All", <%= plural_name %>_path %>
|
10
|
+
<%- end -%>
|
11
|
+
</p>
|
12
|
+
<%- end -%>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<table>
|
2
|
+
<tr>
|
3
|
+
<%- for attribute in attributes -%>
|
4
|
+
<th><%= attribute.column.human_name.titleize %></th>
|
5
|
+
<%- end -%>
|
6
|
+
</tr>
|
7
|
+
<%% for <%= singular_name %> in @<%= plural_name %> %>
|
8
|
+
<tr>
|
9
|
+
<%- for attribute in attributes -%>
|
10
|
+
<td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
|
11
|
+
<%- end -%>
|
12
|
+
<%- if action? :show -%>
|
13
|
+
<td><%%= link_to "Show", <%= singular_name %> %></td>
|
14
|
+
<%- end -%>
|
15
|
+
<%- if action? :edit -%>
|
16
|
+
<td><%%= link_to "Edit", edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
|
17
|
+
<%- end -%>
|
18
|
+
<%- if action? :destroy -%>
|
19
|
+
<td><%%= link_to "Destroy", <%= singular_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
|
20
|
+
<%- end -%>
|
21
|
+
</tr>
|
22
|
+
<%% end %>
|
23
|
+
</table>
|
24
|
+
|
25
|
+
<%- if action? :new -%>
|
26
|
+
<p><%%= link_to "New <%= singular_name.titleize %>", new_<%= singular_name %>_path %></p>
|
27
|
+
<%- end -%>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%- for attribute in attributes -%>
|
2
|
+
<p>
|
3
|
+
<strong><%= attribute.column.human_name.titleize %>:</strong>
|
4
|
+
<%%=h @<%= singular_name %>.<%= attribute.name %> %>
|
5
|
+
</p>
|
6
|
+
<%- end -%>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
<strong>Current state: </strong><%%= @<%= singular_name %>.aasm_state.humanize %>
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<p>
|
13
|
+
<%% @<%= singular_name %>.aasm_events_for_current_state.each do |event| %>
|
14
|
+
<%%= link_to_stonepath_event(@<%= singular_name %>, event) %> |
|
15
|
+
<%% end %>
|
16
|
+
|
17
|
+
<%- if action? :edit -%>
|
18
|
+
<%%= link_to "Edit", edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
|
19
|
+
<%- end -%>
|
20
|
+
<%- if action? :destroy -%>
|
21
|
+
<%%= link_to "Destroy", @<%= singular_name %>, :confirm => 'Are you sure?', :method => :delete %> |
|
22
|
+
<%- end -%>
|
23
|
+
<%- if action? :index -%>
|
24
|
+
<%%= link_to "View All", <%= plural_name %>_path %>
|
25
|
+
<%- end -%>
|
26
|
+
</p>
|
metadata
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stonepath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 961916008
|
5
|
+
prerelease: true
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 4
|
8
|
-
-
|
9
|
-
|
9
|
+
- 3
|
10
|
+
- pre
|
11
|
+
version: 0.4.3.pre
|
10
12
|
platform: ruby
|
11
13
|
authors:
|
12
14
|
- David Bock
|
@@ -25,6 +27,7 @@ dependencies:
|
|
25
27
|
requirements:
|
26
28
|
- - ">="
|
27
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 15
|
28
31
|
segments:
|
29
32
|
- 2
|
30
33
|
- 0
|
@@ -40,6 +43,7 @@ dependencies:
|
|
40
43
|
requirements:
|
41
44
|
- - ">="
|
42
45
|
- !ruby/object:Gem::Version
|
46
|
+
hash: 13
|
43
47
|
segments:
|
44
48
|
- 2
|
45
49
|
- 1
|
@@ -55,6 +59,7 @@ dependencies:
|
|
55
59
|
requirements:
|
56
60
|
- - ">="
|
57
61
|
- !ruby/object:Gem::Version
|
62
|
+
hash: 27
|
58
63
|
segments:
|
59
64
|
- 0
|
60
65
|
- 1
|
@@ -89,6 +94,42 @@ files:
|
|
89
94
|
- lib/stonepath/work_owner.rb
|
90
95
|
- lib/tasks/stonepath.rake
|
91
96
|
- rails/init.rb
|
97
|
+
- rails_generators/stonepath_event_log/stonepath_event_log_generator.rb
|
98
|
+
- rails_generators/stonepath_event_log/templates/create_event_records.rb
|
99
|
+
- rails_generators/stonepath_event_log/templates/event_record.rb
|
100
|
+
- rails_generators/stonepath_task/USAGE
|
101
|
+
- rails_generators/stonepath_task/stonepath_task_generator.rb
|
102
|
+
- rails_generators/stonepath_task/templates/generic_task.rb
|
103
|
+
- rails_generators/stonepath_task/templates/generic_task_migration.rb
|
104
|
+
- rails_generators/stonepath_workitem/USAGE
|
105
|
+
- rails_generators/stonepath_workitem/stonepath_workitem_generator.rb
|
106
|
+
- rails_generators/stonepath_workitem/templates/actions/create.rb
|
107
|
+
- rails_generators/stonepath_workitem/templates/actions/destroy.rb
|
108
|
+
- rails_generators/stonepath_workitem/templates/actions/edit.rb
|
109
|
+
- rails_generators/stonepath_workitem/templates/actions/index.rb
|
110
|
+
- rails_generators/stonepath_workitem/templates/actions/new.rb
|
111
|
+
- rails_generators/stonepath_workitem/templates/actions/show.rb
|
112
|
+
- rails_generators/stonepath_workitem/templates/actions/update.rb
|
113
|
+
- rails_generators/stonepath_workitem/templates/controller.rb
|
114
|
+
- rails_generators/stonepath_workitem/templates/event_controller.rb
|
115
|
+
- rails_generators/stonepath_workitem/templates/fixtures.yml
|
116
|
+
- rails_generators/stonepath_workitem/templates/helper.rb
|
117
|
+
- rails_generators/stonepath_workitem/templates/migration.rb
|
118
|
+
- rails_generators/stonepath_workitem/templates/model.rb
|
119
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/actions/create.rb
|
120
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/actions/destroy.rb
|
121
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/actions/edit.rb
|
122
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/actions/index.rb
|
123
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/actions/new.rb
|
124
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/actions/show.rb
|
125
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/actions/update.rb
|
126
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/controller.rb
|
127
|
+
- rails_generators/stonepath_workitem/templates/tests/testunit/model.rb
|
128
|
+
- rails_generators/stonepath_workitem/templates/views/erb/_form.html.erb
|
129
|
+
- rails_generators/stonepath_workitem/templates/views/erb/edit.html.erb
|
130
|
+
- rails_generators/stonepath_workitem/templates/views/erb/index.html.erb
|
131
|
+
- rails_generators/stonepath_workitem/templates/views/erb/new.html.erb
|
132
|
+
- rails_generators/stonepath_workitem/templates/views/erb/show.html.erb
|
92
133
|
- script/console
|
93
134
|
- script/destroy
|
94
135
|
- script/generate
|
@@ -137,17 +178,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
178
|
requirements:
|
138
179
|
- - ">="
|
139
180
|
- !ruby/object:Gem::Version
|
181
|
+
hash: 3
|
140
182
|
segments:
|
141
183
|
- 0
|
142
184
|
version: "0"
|
143
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
186
|
none: false
|
145
187
|
requirements:
|
146
|
-
- - "
|
188
|
+
- - ">"
|
147
189
|
- !ruby/object:Gem::Version
|
190
|
+
hash: 25
|
148
191
|
segments:
|
149
|
-
-
|
150
|
-
|
192
|
+
- 1
|
193
|
+
- 3
|
194
|
+
- 1
|
195
|
+
version: 1.3.1
|
151
196
|
requirements: []
|
152
197
|
|
153
198
|
rubyforge_project:
|