stonepath 0.1.2 → 0.2.0

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.
Files changed (48) hide show
  1. data/VERSION +1 -1
  2. data/lib/stonepath.rb +2 -3
  3. data/lib/stonepath/extensions/action_view.rb +1 -1
  4. data/lib/stonepath/extensions/rails_generator_commands.rb +42 -0
  5. data/rails_generators/{stonepath → stonepath_event_log}/stonepath_event_log_generator.rb +0 -0
  6. data/rails_generators/{stonepath → stonepath_event_log}/templates/create_event_records.rb +0 -0
  7. data/rails_generators/{stonepath → stonepath_event_log}/templates/event_record.rb +0 -0
  8. data/rails_generators/stonepath_task/USAGE +1 -0
  9. data/rails_generators/stonepath_task/stonepath_task_generator.rb +29 -0
  10. data/rails_generators/stonepath_task/templates/generic_task.rb +23 -0
  11. data/rails_generators/stonepath_task/templates/generic_task_migration.rb +36 -0
  12. data/rails_generators/stonepath_workitem/USAGE +51 -0
  13. data/rails_generators/stonepath_workitem/stonepath_workitem_generator.rb +196 -0
  14. data/rails_generators/stonepath_workitem/templates/actions/create.rb +9 -0
  15. data/rails_generators/stonepath_workitem/templates/actions/destroy.rb +6 -0
  16. data/rails_generators/stonepath_workitem/templates/actions/edit.rb +3 -0
  17. data/rails_generators/stonepath_workitem/templates/actions/index.rb +3 -0
  18. data/rails_generators/stonepath_workitem/templates/actions/new.rb +3 -0
  19. data/rails_generators/stonepath_workitem/templates/actions/show.rb +3 -0
  20. data/rails_generators/stonepath_workitem/templates/actions/update.rb +9 -0
  21. data/rails_generators/stonepath_workitem/templates/controller.rb +3 -0
  22. data/rails_generators/stonepath_workitem/templates/event_controller.rb +25 -0
  23. data/rails_generators/stonepath_workitem/templates/fixtures.yml +9 -0
  24. data/rails_generators/stonepath_workitem/templates/helper.rb +2 -0
  25. data/rails_generators/stonepath_workitem/templates/migration.rb +24 -0
  26. data/rails_generators/stonepath_workitem/templates/model.rb +33 -0
  27. data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/create.rb +11 -0
  28. data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/destroy.rb +6 -0
  29. data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/edit.rb +4 -0
  30. data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/index.rb +4 -0
  31. data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/new.rb +4 -0
  32. data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/show.rb +4 -0
  33. data/rails_generators/stonepath_workitem/templates/tests/testunit/actions/update.rb +11 -0
  34. data/rails_generators/stonepath_workitem/templates/tests/testunit/controller.rb +5 -0
  35. data/rails_generators/stonepath_workitem/templates/tests/testunit/model.rb +7 -0
  36. data/rails_generators/stonepath_workitem/templates/views/erb/_form.html.erb +10 -0
  37. data/rails_generators/stonepath_workitem/templates/views/erb/edit.html.erb +12 -0
  38. data/rails_generators/stonepath_workitem/templates/views/erb/index.html.erb +27 -0
  39. data/rails_generators/stonepath_workitem/templates/views/erb/new.html.erb +5 -0
  40. data/rails_generators/stonepath_workitem/templates/views/erb/show.html.erb +26 -0
  41. metadata +39 -12
  42. data/lib/stonepath/extensions/action_controller.rb +0 -50
  43. data/lib/stonepath/extensions/kernel.rb +0 -5
  44. data/rails_generators/stonepath/stonepath_task_generator.rb +0 -9
  45. data/rails_generators/stonepath/stonepath_workitem_generator.rb +0 -8
  46. data/rails_generators/stonepath/templates/generic_task.rb +0 -8
  47. data/rails_generators/stonepath/templates/generic_task_migration.rb +0 -20
  48. data/rails_generators/stonepath/templates/workitem_readme.txt +0 -14
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
data/lib/stonepath.rb CHANGED
@@ -7,9 +7,10 @@ module StonePath
7
7
 
8
8
  base.instance_eval {
9
9
 
10
- def stonepath_workitem
10
+ def stonepath_workitem(&config_block)
11
11
  require File.expand_path(File.dirname(__FILE__)) + "/stonepath/work_item.rb"
12
12
  include StonePath::WorkItem
13
+ instance_eval &config_block if config_block
13
14
  end
14
15
 
15
16
  def stonepath_task(&config_block)
@@ -51,8 +52,6 @@ require "stonepath/config"
51
52
  # init.rb chokes on load. I suspect this is an artificial issue because of the way the
52
53
  # embedded test app works.
53
54
  load File.expand_path( File.dirname(__FILE__)) + "/stonepath/extensions/activerecordbase.rb"
54
- load File.expand_path( File.dirname(__FILE__)) + "/stonepath/extensions/action_controller.rb"
55
- load File.expand_path( File.dirname(__FILE__)) + "/stonepath/extensions/kernel.rb"
56
55
  load File.expand_path( File.dirname(__FILE__)) + '/stonepath/extensions/action_view.rb'
57
56
 
58
57
 
@@ -6,7 +6,7 @@ if Object.const_defined?(:ActionView)
6
6
  module UrlHelper
7
7
 
8
8
  def link_to_stonepath_event(object, event)
9
- path_method = object.class.to_s.downcase + "_event_path"
9
+ path_method = object.class.to_s.tableize.singularize + "_event_path"
10
10
  path = self.send(path_method, object, :id => event.to_s)
11
11
  link_to(event.to_s.humanize, path, :method => :post)
12
12
  end
@@ -0,0 +1,42 @@
1
+ module Rails
2
+ module Generator
3
+ module Commands
4
+
5
+ Create.class_eval {
6
+ def route_stonepath_workitems(resource)
7
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
8
+ logger.route "map.stonepath_workitems #{resource}"
9
+ unless options[:pretend]
10
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
11
+ "#{match}
12
+
13
+ map.resources :#{resource} do |o|
14
+ o.resource :event, {:only => \"create\", :controller => \"#{resource.singularize}_events\"}
15
+ end
16
+ "
17
+ end
18
+ end
19
+ end
20
+ }
21
+
22
+
23
+ Destroy.class_eval {
24
+ def route_stonepath_workitems(*resources)
25
+ resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
26
+ look_for = "\n map.stonepath_workitems #{resource_list}\n"
27
+ logger.route "map.stonepath_workitems #{resource_list}"
28
+ gsub_file 'config/routes.rb', /(#{look_for})/mi, ''
29
+ end
30
+ }
31
+
32
+
33
+ List.class_eval {
34
+ def route_stonepath_workitems(*resources)
35
+ resource_list = resources.map { |r| r.to_sym.inspect }.join(', ')
36
+ logger.route "map.stonepath_workitems #{resource_list}"
37
+ end
38
+ }
39
+
40
+ end
41
+ end
42
+ 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 <%= 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,6 @@
1
+ def destroy
2
+ @<%= singular_name %> = <%= class_name %>.find(params[:id])
3
+ @<%= singular_name %>.destroy
4
+ flash[:notice] = "Successfully destroyed <%= name.underscore.humanize.downcase %>."
5
+ redirect_to <%= items_path('url') %>
6
+ end
@@ -0,0 +1,3 @@
1
+ def edit
2
+ @<%= singular_name %> = <%= class_name %>.find(params[:id])
3
+ end
@@ -0,0 +1,3 @@
1
+ def index
2
+ @<%= plural_name %> = <%= class_name %>.all
3
+ end
@@ -0,0 +1,3 @@
1
+ def new
2
+ @<%= singular_name %> = <%= class_name %>.new
3
+ end
@@ -0,0 +1,3 @@
1
+ def show
2
+ @<%= singular_name %> = <%= class_name %>.find(params[:id])
3
+ 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,3 @@
1
+ class <%= plural_class_name %>Controller < ApplicationController
2
+ <%= controller_methods :actions %>
3
+ 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,9 @@
1
+ one:
2
+ <%- for attribute in attributes -%>
3
+ <%= attribute.name %>: <%= attribute.default %>
4
+ <%- end -%>
5
+
6
+ two:
7
+ <%- for attribute in attributes -%>
8
+ <%= attribute.name %>: <%= attribute.default %>
9
+ <%- end -%>
@@ -0,0 +1,2 @@
1
+ module <%= plural_class_name %>Helper
2
+ 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,6 @@
1
+ def test_destroy
2
+ <%= singular_name %> = <%= class_name %>.first
3
+ delete :destroy, :id => <%= singular_name %>
4
+ assert_redirected_to <%= items_path('url') %>
5
+ assert !<%= class_name %>.exists?(<%= singular_name %>.id)
6
+ end
@@ -0,0 +1,4 @@
1
+ def test_edit
2
+ get :edit, :id => <%= class_name %>.first
3
+ assert_template 'edit'
4
+ end
@@ -0,0 +1,4 @@
1
+ def test_index
2
+ get :index
3
+ assert_template 'index'
4
+ end
@@ -0,0 +1,4 @@
1
+ def test_new
2
+ get :new
3
+ assert_template 'new'
4
+ end
@@ -0,0 +1,4 @@
1
+ def test_show
2
+ get :show, :id => <%= class_name %>.first
3
+ assert_template 'show'
4
+ 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,5 @@
1
+ require 'test_helper'
2
+
3
+ class <%= plural_class_name %>ControllerTest < ActionController::TestCase
4
+ <%= controller_methods 'tests/testunit/actions' %>
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ def test_should_be_valid
5
+ assert <%= class_name %>.new.valid?
6
+ end
7
+ 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,5 @@
1
+ <%= render_form %>
2
+
3
+ <%- if action? :index -%>
4
+ <p><%%= link_to "Back to List", <%= plural_name %>_path %></p>
5
+ <%- 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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stonepath
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Bock
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-06 00:00:00 -05:00
12
+ date: 2010-01-07 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -45,10 +45,9 @@ files:
45
45
  - lib/stonepath/config.rb
46
46
  - lib/stonepath/controller_hooks.rb
47
47
  - lib/stonepath/event_logging.rb
48
- - lib/stonepath/extensions/action_controller.rb
49
48
  - lib/stonepath/extensions/action_view.rb
50
49
  - lib/stonepath/extensions/activerecordbase.rb
51
- - lib/stonepath/extensions/kernel.rb
50
+ - lib/stonepath/extensions/rails_generator_commands.rb
52
51
  - lib/stonepath/group.rb
53
52
  - lib/stonepath/role.rb
54
53
  - lib/stonepath/task.rb
@@ -56,14 +55,42 @@ files:
56
55
  - lib/stonepath/work_item.rb
57
56
  - lib/stonepath/work_owner.rb
58
57
  - rails/init.rb
59
- - rails_generators/stonepath/stonepath_event_log_generator.rb
60
- - rails_generators/stonepath/stonepath_task_generator.rb
61
- - rails_generators/stonepath/stonepath_workitem_generator.rb
62
- - rails_generators/stonepath/templates/create_event_records.rb
63
- - rails_generators/stonepath/templates/event_record.rb
64
- - rails_generators/stonepath/templates/generic_task.rb
65
- - rails_generators/stonepath/templates/generic_task_migration.rb
66
- - rails_generators/stonepath/templates/workitem_readme.txt
58
+ - rails_generators/stonepath_event_log/stonepath_event_log_generator.rb
59
+ - rails_generators/stonepath_event_log/templates/create_event_records.rb
60
+ - rails_generators/stonepath_event_log/templates/event_record.rb
61
+ - rails_generators/stonepath_task/USAGE
62
+ - rails_generators/stonepath_task/stonepath_task_generator.rb
63
+ - rails_generators/stonepath_task/templates/generic_task.rb
64
+ - rails_generators/stonepath_task/templates/generic_task_migration.rb
65
+ - rails_generators/stonepath_workitem/USAGE
66
+ - rails_generators/stonepath_workitem/stonepath_workitem_generator.rb
67
+ - rails_generators/stonepath_workitem/templates/actions/create.rb
68
+ - rails_generators/stonepath_workitem/templates/actions/destroy.rb
69
+ - rails_generators/stonepath_workitem/templates/actions/edit.rb
70
+ - rails_generators/stonepath_workitem/templates/actions/index.rb
71
+ - rails_generators/stonepath_workitem/templates/actions/new.rb
72
+ - rails_generators/stonepath_workitem/templates/actions/show.rb
73
+ - rails_generators/stonepath_workitem/templates/actions/update.rb
74
+ - rails_generators/stonepath_workitem/templates/controller.rb
75
+ - rails_generators/stonepath_workitem/templates/event_controller.rb
76
+ - rails_generators/stonepath_workitem/templates/fixtures.yml
77
+ - rails_generators/stonepath_workitem/templates/helper.rb
78
+ - rails_generators/stonepath_workitem/templates/migration.rb
79
+ - rails_generators/stonepath_workitem/templates/model.rb
80
+ - rails_generators/stonepath_workitem/templates/tests/testunit/actions/create.rb
81
+ - rails_generators/stonepath_workitem/templates/tests/testunit/actions/destroy.rb
82
+ - rails_generators/stonepath_workitem/templates/tests/testunit/actions/edit.rb
83
+ - rails_generators/stonepath_workitem/templates/tests/testunit/actions/index.rb
84
+ - rails_generators/stonepath_workitem/templates/tests/testunit/actions/new.rb
85
+ - rails_generators/stonepath_workitem/templates/tests/testunit/actions/show.rb
86
+ - rails_generators/stonepath_workitem/templates/tests/testunit/actions/update.rb
87
+ - rails_generators/stonepath_workitem/templates/tests/testunit/controller.rb
88
+ - rails_generators/stonepath_workitem/templates/tests/testunit/model.rb
89
+ - rails_generators/stonepath_workitem/templates/views/erb/_form.html.erb
90
+ - rails_generators/stonepath_workitem/templates/views/erb/edit.html.erb
91
+ - rails_generators/stonepath_workitem/templates/views/erb/index.html.erb
92
+ - rails_generators/stonepath_workitem/templates/views/erb/new.html.erb
93
+ - rails_generators/stonepath_workitem/templates/views/erb/show.html.erb
67
94
  - script/console
68
95
  - script/destroy
69
96
  - script/generate
@@ -1,50 +0,0 @@
1
- if Object.const_defined?(:ActionController)
2
-
3
- module ActionController
4
- module Resources
5
-
6
- def define_events_controller(object_sym)
7
- class_name = object_sym.to_s.classify
8
- controller_name = class_name + "EventsController"
9
-
10
- # This is some amazing bit of meta that will probably go away when we have
11
- # a work_item generator. In short, at runtime, this defines the controller
12
- # that handles events for something declared in the routes file as a
13
- # stonepath_workitem
14
- Object.const_set(controller_name, ApplicationController.clone).class_eval do
15
- id_name = (class_name.downcase + "_id").to_sym
16
- #still need generic http error handling
17
- define_method("create") do
18
- if request.post?
19
- @object = get_class(class_name).find(params[id_name])
20
- event = params[:id]
21
- if get_class(class_name).aasm_events.keys.include?(event.to_sym)
22
- respond_to do |format|
23
- if @object.send(event + "!")
24
- flash[:notice] = "Event '#{event}' was successfully performed."
25
- format.html { redirect_to(@object) }
26
- format.xml { render :xml => @object }
27
- else
28
- flash[:notice] = "Event '#{event}' was NOT successfully performed."
29
- format.html { redirect_to(@object) }
30
- format.xml { render :xml => @object.errors, :status => :unprocessable_entity }
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
37
-
38
- end
39
-
40
- def stonepath_workitems(resources_symbol, params={})
41
- singular_resource_name = resources_symbol.to_s.singularize
42
- self.resources resources_symbol, params do |o|
43
- o.resource :event, {:only => "create", :controller => "#{singular_resource_name}_events"}
44
- end
45
- define_events_controller(resources_symbol)
46
- end
47
- end
48
- end
49
-
50
- end
@@ -1,5 +0,0 @@
1
- module Kernel
2
- def get_class(name)
3
- self.class.const_get(name)
4
- end
5
- end
@@ -1,9 +0,0 @@
1
- class StonepathTaskGenerator < Rails::Generator::Base
2
- def manifest
3
- record do |m|
4
- task_name = args[0]
5
- m.template('generic_task.rb', "app/models/#{task_name}.rb")
6
- m.migration_template("generic_task_migration.rb", "db/migrate", :migration_file_name => "create_#{task_name.tableize}")
7
- end
8
- end
9
- end
@@ -1,8 +0,0 @@
1
- class StonepathWorkitemGenerator < Rails::Generator::Base
2
- def manifest
3
- record do |m|
4
- task_name = args[0]
5
- m.readme("workitem_readme.txt")
6
- end
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- class <%= args[0].classify %> < ActiveRecord::Base
2
- include StonePath
3
-
4
- stonepath_task
5
-
6
- #logs_transitions
7
-
8
- end
@@ -1,20 +0,0 @@
1
- class Create<%= args[0].tableize.classify.pluralize %> < ActiveRecord::Migration
2
- def self.up
3
- create_table :<%= args[0].tableize %> do |t|
4
-
5
- t.string :aasm_state
6
- t.references :workitem, :polymorphic => true
7
- t.references :workbench, :polymorphic => true
8
-
9
- t.datetime :due_at
10
- t.datetime :completed_at
11
- t.timestamps
12
-
13
- # customize your task here
14
- end
15
- end
16
-
17
- def self.down
18
- drop_table :<%= args[0].tableize %>
19
- end
20
- end
@@ -1,14 +0,0 @@
1
- We will eventually have a real generator here that will even include some default config for AASM settings, restful routes for the workflow actions, etc. Until then, it would be best to start a workitem by:
2
-
3
- 1) Using scaffold generator
4
- 2) adding aasm_state:string and owner_id:integer to the migration.
5
- 3) adding:
6
-
7
- require 'aasm'
8
- require 'stonepath'
9
-
10
- stonepath_workitem
11
-
12
- to the model
13
-
14
- 4) defining a state machine.