Sha256: 85e5ddc013dfd2bd2987f8bbb78ac4e96f27a7ea3e09ee2732ed95fee40cb910

Contents?: true

Size: 1.41 KB

Versions: 2

Compression:

Stored size: 1.41 KB

Contents

require 'rom/header'
require 'rom/repository/struct_builder'

module ROM
  class Repository
    # @api private
    class HeaderBuilder
      attr_reader :struct_builder

      def initialize
        @struct_builder = StructBuilder.new
      end

      def call(ast)
        Header.coerce(*visit(ast))
      end
      alias_method :[], :call

      private

      def visit(node, *args)
        name, node = node
        __send__("visit_#{name}", node, *args)
      end

      def visit_relation(node, meta = {})
        relation_name, meta, header = node
        name = meta[:combine_name] || relation_name

        model = meta.fetch(:model) do
          struct_builder[meta.fetch(:dataset), header]
        end

        options = [visit(header, meta), model: model]

        if meta[:combine_type]
          type = meta[:combine_type] == :many ? :array : :hash
          keys = meta.fetch(:keys)

          [name, combine: true, type: type, keys: keys, header: Header.coerce(*options)]
        elsif meta[:wrap]
          [name, wrap: true, type: :hash, header: Header.coerce(*options)]
        else
          options
        end
      end

      def visit_header(node, meta = {})
        node.map { |attribute| visit(attribute, meta) }
      end

      def visit_attribute(name, meta = {})
        if meta[:wrap]
          [name, from: :"#{meta[:dataset]}_#{name}"]
        else
          [name]
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
rom-repository-0.3.1 lib/rom/repository/header_builder.rb
rom-repository-0.3.0 lib/rom/repository/header_builder.rb