# dry-transformer get a value from hash

**URL:** <https://discourse.dry-rb.org/t/dry-transformer-get-a-value-from-hash/1755>\
**Category:** Support\
**Created:** [November 20, 2023, 1:24am UTC](https://discourse.dry-rb.org/t/dry-transformer-get-a-value-from-hash/1755 "2023-11-20T01:24:55Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![igas](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/igas/32/934_2.png) [@igas](https://discourse.dry-rb.org/u/igas)\
**Post date:** [November 20, 2023, 1:24am UTC](https://discourse.dry-rb.org/t/dry-transformer-get-a-value-from-hash/1755/1 "2023-11-20T01:24:55Z")

</div>

I have an input:

```json
{
  "job_status": "SUCCEEDED",
  "expense_documents": [
    {"type": "total"},
    {"type": "tax"}
  ]
}

```

I want to get:

```json
[{"type": "total"},{"type": "tax"}]

```

Simplified example, I do more processing, but essentially I can’t find a DSL to get a value.

```ruby
define! do
  unwrap "expense_documents"
end

```

Fails, I think it expects hash as a value.

```auto
wrong element type Hash at 0 (expected array)
dry/transformer/hash_transformations.rb:284

```

Am I missing something or use it in a wrong way?

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/alassek/32/314_2.png) [@alassek](https://discourse.dry-rb.org/u/alassek)\
**Post date:** [November 21, 2023, 5:41pm UTC](https://discourse.dry-rb.org/t/dry-transformer-get-a-value-from-hash/1755/2 "2023-11-21T17:41:12Z")

</div>

If you look at the [API documentation](https://www.rubydoc.info/gems/dry-transformer/Dry/Transformer/HashTransformations), you’ll see that `unwrap` has a signature of `.unwrap(source_hash, root, selected = nil, prefix: false) ⇒ Hash`. So it assumes that it is merging the nested key into the top-level.

Scanning through the list looking at the type signatures, none of the existing transformations perform this kind of type transformation in the way you need.

In this situation, you can easily add your own transform method.

Easiest and most direct way is just define a method in the transformer object

```ruby
#!/usr/bin/env ruby

require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "dry-transformer"
end

require "dry/transformer"

class JobMapper < Dry::Transformer::Pipe
  import Dry::Transformer::HashTransformations

  define! do
    extract_expenses
  end

  def extract_expenses(job)
    job.fetch(:expense_documents)
  end
end

puts JobMapper.new.({
  job_status: "SUCCEEDED",
  expense_documents: [
    { type: "total" },
    { type: "tax" }
  ]
}).inspect

```

Eventually you’ll want to share custom methods with multiple transformers, you can do that with a registry.

```ruby
#!/usr/bin/env ruby

require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "dry-transformer"
end

require "dry/transformer"

module MyRegistry
  extend Dry::Transformer::Registry

  import Dry::Transformer::HashTransformations

  register :map_subkey do |hash, key|
    hash.fetch(key).then { Array(_1) }
  end
end

class JobMapper < Dry::Transformer::Pipe
  import MyRegistry

  define! do
    map_subkey :expense_documents
  end
end

puts JobMapper.new.({
  job_status: "SUCCEEDED",
  expense_documents: [
    { type: "total" },
    { type: "tax" }
  ]
}).inspect

```
