stonepath 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.