Module: Workflow
- Defined in:
- lib/workflow.rb,
lib/workflow/state_dependent_validations.rb
Overview
See also README.markdown for documentation
Defined Under Namespace
Modules: StateDependentValidations, 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
Instance Method Summary collapse
-
#workflow_diagram(graph_options) ⇒ Object
Returns a representation of the state diagram for the calling model as a string in dot language.
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
404 405 406 407 408 409 410 411 412 |
# File 'lib/workflow.rb', line 404 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 klass.new.workflow_diagram() end `dot -Tpdf -o'#{fname}.pdf' '#{fname}.dot'` puts "A PDF file was generated at '#{fname}.pdf'" end |
.included(klass) ⇒ Object
365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'lib/workflow.rb', line 365 def self.included(klass) klass.send :include, WorkflowInstanceMethods klass.extend WorkflowClassMethods # [ActiveModelPersistence, MongoidPersistence, RemodelPersistence].each do |konst| # if konst.happy_to_be_included_in? klass # raise "including #{konst}" # raise "including #{konst}" # klass.send :include, konst # end # end end |
Instance Method Details
#workflow_diagram(graph_options) ⇒ Object
Returns a representation of the state diagram for the calling model as a string in dot language. See Workflow.create_workflow_diagram for more deails
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/workflow.rb', line 417 def workflow_diagram() str = <<-EOS digraph #{self.class} { graph [#{}]; node [shape=box]; edge [len=1]; EOS self.class.workflow_spec.states.each do |state_name, state| = state. if state == self.class.workflow_spec.initial_state str << %Q{ #{state.name} [label="#{state.name}", shape=circle];\n} else str << %Q{ #{state.name} [label="#{state.name}", shape=#{[:terminal] ? 'doublecircle' : 'box, style=rounded'}];\n} end state.events.each do |event_name, event| = event. [:doc_weight] = 6 if [:main_path] if [:doc_weight] weight_prop = ", weight=#{[:doc_weight]}, penwidth=#{[:doc_weight] / 2 || 0.0}\n" else weight_prop = '' end str << %Q{ #{state.name} -> #{event.transitions_to} [label="#{event_name.to_s.humanize}" #{weight_prop}];\n} end end str << "}\n" return str end |