Skip to content

transform

rel.transform(attr: :upcase)
rel.transform(attr: ->(v) { v * 2 })
rel.transform(attr: Integer)
rel.transform(:downcase)
rel.transform { |v| v.to_s }

Modify existing attribute values in place using transformations.

Example: I want to normalize all string values to uppercase, or convert all numeric strings to integers.

The transform operator modifies existing attribute values (unlike extend which adds new attributes).

It supports several transformation styles:

Per-attribute transformation (Hash): attr: :method (call method), attr: Class (type conversion), attr: ->(v) { ... } (lambda), attr: { old => new } (value mapping), or Class => transformer (by type).

All-attributes transformation: Pass a Symbol (:downcase) or Proc to transform every value.

No special requirements. Works on any relation.

data = Bmg::Relation.new([
{ id: 1, name: "alice", email: "ALICE@EXAMPLE.COM" },
{ id: 2, name: "bob", email: "BOB@EXAMPLE.COM" }
])
data.transform(name: :capitalize, email: :downcase).to_a
=>
[{:id=>1, :name=>"Alice", :email=>"alice@example.com"},
{:id=>2, :name=>"Bob", :email=>"bob@example.com"}]
orders = Bmg::Relation.new([
{ id: 1, total: 100, discount: 0.1 },
{ id: 2, total: 200, discount: 0.2 }
])
orders.transform(
total: ->(v) { v.round(2) },
discount: ->(v) { "#{(v * 100).to_i}%" }
).to_a
=>
[{:id=>1, :total=>100, :discount=>"10%"},
{:id=>2, :total=>200, :discount=>"20%"}]
OperatorPurposeResult
transformModify existing valuesSame attributes, different values
extendAdd new attributesAdditional attributes
# transform: modifies existing attribute
rel.transform(name: :upcase)
# { name: "alice" } => { name: "ALICE" }
# extend: adds new attribute
rel.extend(upper_name: ->(t) { t[:name].upcase })
# { name: "alice" } => { name: "alice", upper_name: "ALICE" }