class FieldMaskParser::Parser

Public Class Methods

new(paths:, root:, dispatcher: nil) click to toggle source

@param [<String>] paths

# File lib/field_mask_parser/parser.rb, line 7
def initialize(paths:, root:, dispatcher: nil)
  @attrs_or_assocs = DeepHashBuilder.build(paths)
  @root            = root
  @dispatcher      = dispatcher || Dispatcher::ActiveRecordDispatcher.new
end

Public Instance Methods

parse() click to toggle source

@reutrn [Node]

# File lib/field_mask_parser/parser.rb, line 14
def parse
  r = Node.new(name: nil, is_leaf: false, klass: @root)
  set_attrs_and_assocs!(r, @attrs_or_assocs, @root)
  r
end

Private Instance Methods

get_assoc_klass(parent, name) click to toggle source

@param [Class] parent @param [Symbol] name @return [Class]

# File lib/field_mask_parser/parser.rb, line 55
def get_assoc_klass(parent, name)
  assocition = parent.reflect_on_association(name)
  if !assocition
    raise "#{parent} does not have #{name} assocition!"
  end
  assocition.klass
end
set_attrs_and_assocs!(node, attrs_or_assocs, klass) click to toggle source

@param [Node] node @param [{ Symbol => DeepHashNode }] attrs_or_assocs @param [Class] klass inheriting ActiveRecord::Base

# File lib/field_mask_parser/parser.rb, line 25
def set_attrs_and_assocs!(node, attrs_or_assocs, klass)
  attrs_or_assocs.each do |name, dhn|
    type = @dispatcher.dispatch(klass, name)

    case type
    when Dispatcher::Type::ATTRIBUTE
      # NOTE: If dhn.is_leaf is false, it is invalid. But ignore it now.
      node.push_attr(name)
    when Dispatcher::Type::HAS_ONE, Dispatcher::Type::HAS_MANY
      _klass = get_assoc_klass(klass, name)
      n = Node.new(name: name, is_leaf: dhn.is_leaf, klass: _klass)
      if type == Dispatcher::Type::HAS_ONE
        node.push_has_one(n)
      else  # Dispatcher::Type::HAS_MANY
        node.push_has_many(n)
      end
      if dhn.children.size > 0
        set_attrs_and_assocs!(n, dhn.children, _klass)
      end
    when Dispatcher::Type::UNKNOWN
      # Ignore invalid field
    else
      raise "invalid type (#{@dispatcher.dispatch(klass, name)}) with klass (#{klass}) and name (#{name})"
    end
  end
end