Module: Workflow
- Defined in:
- lib/workflow.rb
Overview
See also README.markdown for documentation
Defined Under Namespace
Modules: ActiveRecordInstanceMethods, RemodelInstanceMethods, WorkflowClassMethods, WorkflowInstanceMethods Classes: Event, NoTransitionAllowed, Specification, State, TransitionHalted, WorkflowDefinitionError, WorkflowError
Class Method Summary collapse
-
.create_workflow_diagram(klass, target_dir = '.', graph_options = 'rankdir="LR", size="7,11.6", ratio="fill"') ⇒ Object
Generates a ‘dot` graph of the workflow.
- .included(klass) ⇒ Object
Class Method Details
.create_workflow_diagram(klass, target_dir = '.', graph_options = 'rankdir="LR", size="7,11.6", ratio="fill"') ⇒ Object
Generates a ‘dot` graph of the workflow. Prerequisite: the `dot` binary. (Download from www.graphviz.org/) You can use this method in your own Rakefile like this:
namespace :doc do
desc "Generate a graph of the workflow."
task :workflow => :environment do # needs access to the Rails environment
Workflow::create_workflow_diagram(Order)
end
end
You can influence the placement of nodes by specifying additional meta information in your states and transition descriptions. You can assign higher ‘doc_weight` value to the typical transitions in your workflow. All other states and transitions will be arranged around that main line. See also `weight` in the graphviz documentation. Example:
state :new do
event :approve, :transitions_to => :approved, :meta => {:doc_weight => 8}
end
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
# File 'lib/workflow.rb', line 338 def self.create_workflow_diagram(klass, target_dir='.', ='rankdir="LR", size="7,11.6", ratio="fill"') workflow_name = "#{klass.name.tableize}_workflow".gsub('/', '_') fname = File.join(target_dir, "generated_#{workflow_name}") File.open("#{fname}.dot", 'w') do |file| file.puts %Q| digraph #{workflow_name} { graph [#{}]; node [shape=box]; edge [len=1]; | klass.workflow_spec.states.each do |state_name, state| file.puts %Q{ #{state.name} [label="#{state.name}"];} state.events.each do |event_name, event| = event. if [:doc_weight] weight_prop = ", weight=#{[:doc_weight]}" else weight_prop = '' end file.puts %Q{ #{state.name} -> #{event.transitions_to} [label="#{event_name.to_s.humanize}" #{weight_prop}];} end end file.puts "}" file.puts end `dot -Tpdf -o'#{fname}.pdf' '#{fname}.dot'` puts " Please run the following to open the generated file: open '#{fname}.pdf' " end |
.included(klass) ⇒ Object
297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/workflow.rb', line 297 def self.included(klass) klass.send :include, WorkflowInstanceMethods klass.extend WorkflowClassMethods if Object.const_defined?(:ActiveRecord) if klass < ActiveRecord::Base klass.send :include, ActiveRecordInstanceMethods klass.before_validation :write_initial_state end elsif Object.const_defined?(:Remodel) if klass < Remodel::Entity klass.send :include, RemodelInstanceMethods end end end |