Class: Kiba::Extend::Transforms::Append::ConvertedValueAndUnit

Inherits:
Object
  • Object
show all
Defined in:
lib/kiba/extend/transforms/append/converted_value_and_unit.rb

Overview

Note:

Currently does NOT work for multivalue value/unit fields. Will return the original values if the given delim parameter value is present in either value or unit field

Converts a given measurement to a different unit and appends the converted value and unit to the original value and unit fields.

This transform makes a number of strong assumptions, largely based on CollectionSpace data migration needs. The major ones, which are not overrideable via parameters, include:

  • one field contains a single numeric/decimal measurement value
  • another field contains a single string measurement unit value
  • each of these measurements should be converted to one additional unit, with the converted value/unit appended to the appropriate field

Others include:

  • the default unit strings configured in the transform are those used in the CollectionSpace measurementUnits vocabulary
  • standard variants of a unit known by Measured gem are handled seamlessly (i.e. foot, ft, feet)

This transform depends upon the Measured gem

Example 1 - Default assumptions

Input table:

| value | unit        |
|-------+-------------|
| nil   | nil         |
| 1.5   | nil         |
| 1.5   | inches      |
| 1.5   | in.         |
| 5     | centimeters |
| 2     | feet        |
| 2     | meters      |
| 2     | pounds      |
| 2     | kilograms   |
| 2     | ounces      |
| 200   | grams       |

Used in pipeline as:

 transform Append::ConvertedValueAndUnit,
   value: :value,
   unit: :unit,
   delim: '|',
   places: 2

Results in:

| value    | unit               |
|----------+--------------------|
| nil      | nil                |
| 1.5      | nil                |
| 1.5|3.81 | inches|centimeters |
| 1.5|3.81 | in.|centimeters    |
| 5|1.97   | centimeters|inches |
| 2|0.61   | feet|meters        |
| 2|6.56   | meters|feet        |
| 2|0.91   | pounds|kilograms   |
| 2|4.41   | kilograms|pounds   |
| 2|56.7   | ounces|grams       |
| 200|7.05 | grams|ounces       |

Example 2 - Using a common conversion that isn’t configured yet

The units that the Measured gem can handle are listed here. If you want to use one of those, that isn’t configured by default in the transform, you must customize one parameter:

  • conversions (to indicate that the new unit should be converted to another, or that another unit should be converted to the new unit

You will not need to pass in conversion_amounts, as Measured already knows how to convert these units.

Input table:

| value | unit   |
|-------+--------|
| 1     | yard   |
| 36    | inches |

Used in pipeline as:

 transform Append::ConvertedValueAndUnit,
   value: :value,
   unit: :unit,
   delim: '|',
   places: 2,
   conversions: {'inches'=>'yards', 'yards'=>'feet'}

Results in:

| value | unit      |
|-------+-----------|
| 1|3   | yard|feet |
| 36|1  | inches|yd |

Example 3 - Fully custom conversions for unknown units

Input table:

| value | unit  |
|-------+-------|
| 4     | hops  |
| 15    | leaps |

Used in pipeline as:

 transform Append::ConvertedValueAndUnit,
   value: :value,
   unit: :unit,
   delim: '|',
   places: 2,
   conversions: {'hops'=>'jumps', 'leaps'=>'hops'},
   conversion_amounts: {
     leaps: [10, :hops],
     hops: [0.25, :jumps]
   }

Results in:

| value  | unit       |
|--------+------------|
| 4|1    | hops|jumps |
| 15|150 | leaps|hops |

Example 4 - overriding default conversions

By default, if the existing unit is inches, the conversion will be to centimeters. The following shows how to convert to feet instead of centimeters

Input table:

| value | unit    |
|-------+---------|
| 36    | inches  |

Used in pipeline as:

transform Append::ConvertedValueAndUnit,
  value: :value,
  unit: :unit,
  delim: '|',
  places: 2,
  conversions: {'inches'=>'feet'}

Results in:

| value | unit         |
|-------+--------------|
| 36|3  | inches|feet  |

Example 5 - overriding default converted unit name

By default, if the existing unit is converted to centimeters, the appended unit value will be “centimeters”. If you find that cumbersome and want to output “cm” instead:

Input table:

| value | unit    |
|-------+---------|
| 36    | inches  |

Used in pipeline as:

transform Append::ConvertedValueAndUnit,
  value: :value,
  unit: :unit,
  delim: '|',
  places: 2,
  unit_names: {'centimeters'=>'cm'}

Results in:

| value    | unit      |
|----------+-----------|
| 36|91.44 | inches|cm |

Constant Summary collapse

CONVERSIONS =

What unit the given unit will be converted to

Any custom conversions given are merged into this, so you can override the defaults

{
  "inches" => "centimeters",
  "centimeters" => "inches",
  "feet" => "meters",
  "meters" => "feet",
  "kilograms" => "pounds",
  "pounds" => "kilograms",
  "ounces" => "grams",
  "grams" => "ounces"
}
UNIT_TYPES =

Used internally. You cannot override these

{
  "inches" => Measured::Length,
  "centimeters" => Measured::Length,
  "feet" => Measured::Length,
  "meters" => Measured::Length,
  "kilograms" => Measured::Weight,
  "pounds" => Measured::Weight,
  "ounces" => Measured::Weight,
  "grams" => Measured::Weight
}
UNIT_NAMES =

Convert the value of Measured::Unit.name to unit name expected by your application

By default, these are set up to output unit names as found in CollectionSpace’s measurementunits option list. Override these by passing in unit_names parameter

{
  "cm" => "centimeters",
  "ft" => "feet",
  "g" => "grams",
  "in" => "inches",
  "kg" => "kilograms",
  "lb" => "pounds",
  "m" => "meters",
  "oz" => "ounces"
}

Instance Method Summary collapse

Constructor Details

#initialize(value:, unit:, places:, delim: Kiba::Extend.delim, conversions: {}, conversion_amounts: {}, unit_names: {}) ⇒ ConvertedValueAndUnit

Note:

See the examples for how to set the conversions, conversion_amounts, and unit_names parameters

Returns a new instance of ConvertedValueAndUnit.

Parameters:

  • value (Symbol)

    name of field containing measurement value

  • unit (Symbol)

    name of field containing measurement unit

  • places (Integer)

    number of decimal places to keep in converted values

  • delim (String) (defaults to: Kiba::Extend.delim)

    delimiter used when appending value to value and unit fields

  • conversions (Hash) (defaults to: {})

    specify what new unit existing values should be converted to

  • conversion_amounts (Hash) (defaults to: {})

    specify conversion rates for new units

  • unit_names (Hash) (defaults to: {})

    specify the desired converted-to unit name to append to field



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/kiba/extend/transforms/append/converted_value_and_unit.rb', line 285

def initialize(value:, unit:, places:, delim: Kiba::Extend.delim,
  conversions: {}, conversion_amounts: {}, unit_names: {})
  @value = value
  @unit = unit
  @places = places
  @delim = delim
  @types = UNIT_TYPES
  @conversions = CONVERSIONS.merge(conversions)
  type_conversions(conversions)
  @unit_names = UNIT_NAMES.merge(unit_names)
  unless conversion_amounts.empty?
    set_up_custom_conversions(conversion_amounts)
    customize_types(conversion_amounts)
  end
end

Instance Method Details

#process(row) ⇒ Object

Parameters:

  • row (Hash{ Symbol => String, nil })


302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/kiba/extend/transforms/append/converted_value_and_unit.rb', line 302

def process(row)
  value = row.fetch(@value, nil)
  unit = row.fetch(@unit, nil)
  return row if value.blank? || unit.blank?
  return row if multival?(value) || multival?(unit)
  return unknown_unit_type(unit, row) unless known_unit_type?(unit)
  return unknown_conversion(unit, row) unless known_conversion?(unit)
  return not_convertable(unit, row) unless convertable?(unit)

  measured = measured_conversion(value, unit)
  return row if measured == :failure

  converted = measured.convert_to(@conversions[unit])
  conv_value = converted.value
    .to_f
    .round(@places)
    .to_s
    .delete_suffix(".0")
  row[@value] = [value, conv_value].join(@delim)
  row[@unit] = [unit, unit_name(converted.unit)].join(@delim)
  row
end