Module: Workflow
- Defined in:
- lib/workflow.rb,
lib/workflow/transactional.rb,
lib/workflow/mongoid_persistence.rb,
lib/workflow/remodel_persistence.rb,
lib/workflow/active_model_persistence.rb,
lib/workflow/state_dependent_validations.rb
Overview
Provides transaction rollback on halt. For now, you can choose between normal halt without any change to ordinary persistence (halt) or halt with transaction rollback (halt_with_rollback!), which will raise an ActiveRecord::Rollback exception. So this only works with ActiveRecord atm.
Defined Under Namespace
Modules: ActiveModelPersistence, MongoidPersistence, RemodelPersistence, StateDependentValidations, Transactional, 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
409 410 411 412 413 414 415 416 417 |
# File 'lib/workflow.rb', line 409 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
370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/workflow.rb', line 370 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
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
# File 'lib/workflow.rb', line 422 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 |