Ruby Syntax

Derick Larson
Workflow Administrators and Developers
The Advanced articles are for administrators and developers that have completed the Basic class.
5.x

Introduction

Ruby is the programming language used by the Task Workflow engine. It is a scripting engine that is used in handlers, node parameters, and connectors. While the syntax is specific to Ruby, much of it will be familiar if you have used any other programming language.

Goals

The goals for the article are:

  • Understand where Ruby is used in Task
  • Be able to test Ruby expressions
  • Understand basic Ruby Syntax used in trees and routines

What is Ruby and Why do we use it

Here's a basic overview of Ruby - https://www.ruby-lang.org/en/

Ruby Documentation is here - https://ruby-doc.org/

Technically we use jRuby in Task (ruby compiled to java), but it is easiest to think of it as "just" Ruby.

IRB

You can use Ruby on your local machine if you have it installed using something called IRB. It lets you run commands from your comand line.

Here is an "official" tutorial, there are a ton more avaialble - Ruby Lang IRB

ERB Tags

Whenever you are trying to execute Ruby code within a PArameter, remember to enclose the entire string within one set of ERB tags. You don't need to include tags for every @values, @result, etc.

WHen you are executing code in a connector, you do not use ERB tags. The tak engine knows that anything in a connector expression is there to be evaluated to true or false.

If-Then Operation

One of the most often used conditional statements id the If-Then-Else.

Here's the basic statement:

if condition
  Statement
end

Adding an Else
if condition
  Statement
else
  Statement
end

Conditional operators include all the standards, <, >, ==, <=, >=, !=

There is also a shortcut called a ternary operator.

Conditional ? true statement : false statement

To and From JSON

JSON is the standard for moving information through Task. We often return information as a json string, and many of the Create handlers use JSON when adding values to fields on a form.

Here is some basic JSON:

{
  "name":"John", 
  "age":31, 
  "city":"New York"
}

to_json

To create JSON, Ruby has a method to_json. This method is used to turn a hash into JSON.

From one of the parameters in a Create User node.

<%=
phone_number = @values['Phone Number'].to_s.empty? ? [] : [@values['Phone Number']]
{
  "First Name" => [@values['First Name']],
  "Last Name"  => [@values['Last Name']],
  "Work Phone" => phone_number,
  "Cell Phone" => phone_number
}.to_json%>

Notice the ternary operator at the beginning for phone_number

So the hash {..stuff..} is converted to JSON when the engine evaluates the code between the ERB tags.

JSON.parse

JSON.parse is the Ruby way to get values out of a JSON string. Here is a further example from the Create User node:

JSON.parse(@results['Approval Task']['Fields JSON'])['Space Admin']

If we had the following JSON string

{
  "username" : "hsolo",
  "Space Admin" : "true"
}

the returned value is: true

Strftime

Ruby strftime is used to format time strings for a little nicer outout.

A normal output of a Date|Time is YYYY-MM-DDTHH:MM:SS+/-timezone offset. 2018-08-10T04:10:06+04:30 is an example

If you wanted to nicely format the Date for a log or comments you could do something like this:

<%=
require 'date'
x = DateTime.parse(@values['When Should Cleaning Happen'])
x.strftime("%F")
 %>

Output - 2020-05-18

Here are some other operators you can use:

Code Description
%d Day of the month (01..31)
%m Month of the year (01..12) Use %-m for (1..12)
%k Hour (0..23)
%M Minutes
%S Seconds (00..60)
%I Hour (1..12)
%p AM/PM
%Y Year
%A Day of the week (name)
%B Month (name)

Comments

Comments are a way to explain and enhance your code. In Ruby, comments begin with a #. There are a few other ways to add commetns, but the limitations of using them in parameters in a node mean that using a # is the easiest way.

Example froma Submission config routine:

<%=
# Parse Source Data values
data = JSON.parse(@inputs['Source Data'])['values']
# Loop over each value and remove nil's and join arrays
result = {}
# Requested For
if data['Requested For Display Name'].nil?
  result['Requested For'] = data['Requested For']
else
  result['Requested For'] = "#{data['Requested For Display Name']} (#{data['Requested For']})"
end

has_key?

When you need to see if a node was executed or if a hash exists the most common option is to use the method .has_key?

Example of using in a connector:

@results.has_key?('Test Node 1')

The above evaluates to either true of false

An example of using it in a parameter:

<%=
if @results.has_key?('Test Node 1')
    @results['Test Node 1']['output']
else
    "Test Node 1 did not execute"
end
%>

Best Practices

The following article describes some best practices for using Ruby in the task engine:

Consistency in Workflow

In the Next Article

In the next article, we'll look at Using Loop Results.

Activity

  • Use an echo node to experiment with an if-then statement.
  • Use .has_key in an expression
  • Convert the answer of a Date|Time question to another format with strftime