How do I use mapping with a repository?

Hello!

Thanks for making a really interesting and feature filled project!

Context

  • I want to be able to transform a response from an API
  • The attributes are nested within ‘attributes’ key for each object

My Problem

I got the mapping working fine without a repository. The moment I call the mapping within the repository I get an error:

undefined method `[]' for #<ROM::OpenStruct:0x00007f944fd51ef8>

The Code

require File.expand_path('../notes/notes.rb', __FILE__)
require 'rom/transformer'

module ROM
  module SimplePracticeAdapter
    class Gateway < ROM::Gateway
      attr_reader :datasets

      def initialize
        @datasets = Hash.new { |h, k| h[k] = [] }
      end

      def dataset(name)
        SimplePractice::API::Client.new # Not included for brevity
      end

      def dataset?(name)
        name.to_sym == :clients
      end
    end
  end
end

module ROM
  module SimplePracticeAdapter
    class Relation < ROM::Relation
      adapter :simple_practice

      forward :show, :index
    end
  end
end

ROM.register_adapter(:simple_practice, ROM::SimplePracticeAdapter)

rom = ROM.container(:simple_practice) do |config|
  class Clients < ROM::Relation[:simple_practice]
    schema(infer: true)
  end
  config.register_relation(Clients)

  module SimplePractice
    module Mappers
      class UnwrapAttributes < ROM::Transformer
        relation :clients
        register_as :unwrap_attributes

        map_array do
          unwrap 'attributes'
        end
      end

      require 'dry/inflector'

      class SnakeCase < ROM::Transformer
        relation :clients
        register_as :snake_case

        map_array do
          map_keys ->(key) { Dry::Inflector.new.underscore(key) }
          symbolize_keys
        end
      end
    end
  end
  config.register_mapper(SimplePractice::Mappers::UnwrapAttributes, SimplePractice::Mappers::SnakeCase)
end

class ClientsRepo < ROM::Repository[:clients]
  def all
    clients.map_with(:unwrap_attributes, :snake_case).index.to_a
  end
end

clients_repo = ClientsRepo.new(rom)
pp clients_repo.all

It’s obviously something silly I’m doing… where is the right place to do the map_with?

Also, it’d be nice if I could just configure the mappers once - so some kind of default “Always use these mappers for this relation”…

Thanks for the help!