datamapper/dm-mapper

View on GitHub
lib/rom/mapping/definition.rb

Summary

Maintainability
A
0 mins
Test Coverage
# encoding: utf-8

module ROM
  class Mapping

    # Mapping definition DSL
    #
    # @private
    class Definition
      include Adamantium::Flat

      attr_reader :mapping, :attributes
      private :mapping, :attributes

      # Build new mapping definition
      #
      # @api private
      def self.build(header, &block)
        new(header, &block)
      end

      # Initialize a new Definition instance
      #
      # @return [undefined]
      #
      # @api private
      def initialize(header, &block)
        @header     = header
        @mapping    = {}
        @attributes = Set.new

        instance_eval(&block)

        build_mapper unless mapper
      end

      # @api private
      def header
        @header.project(attributes + Set[*mapping.keys])
      end
      memoize :header

      # Get or set mapper
      #
      # @example
      #
      #   Mapping.build do
      #     users do
      #       mapper my_custom_mapper
      #     end
      #   end
      #
      # @param [Object]
      #
      # @return [Object]
      #
      # @api public
      def mapper(mapper = Undefined)
        if mapper == Undefined
          @mapper
        else
          @mapper = mapper
        end
      end

      # Get or set model for the mapper
      #
      # @example
      #
      #   Mapping.build do
      #     users do
      #       model User
      #     end
      #   end
      #
      # @param [Class]
      #
      # @return [Class]
      #
      # @api public
      def model(model = Undefined)
        if model == Undefined
          @model
        else
          @model = model
        end
      end

      # Configure attribute mappings
      #
      # @example
      #
      #   Mapping.build do
      #     users do
      #       map :id, :email
      #       map :user_name, to: :name
      #     end
      #   end
      #
      # @params [Array<Symbol>,Symbol,Hash]
      #
      # @return [Definition]
      #
      # @api public
      def map(*args)
        options = args.last

        if options.kind_of?(Hash)
          mapping.update(args.first => options[:to])
        else
          @attributes += Set[*args]
        end
      end

      private

      # Build default rom mapper
      #
      # @api private
      def build_mapper
        @mapper = Mapper.build(header, model, map: mapping)
      end

    end # Definition

  end # Mapping
end # ROM