class Visitors::ToHash

Attributes

_resource[R]

Public Class Methods

new(view_context, resource = nil) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 7
def initialize(view_context, resource = nil)
  @_context  = view_context
  @_result   = {}
  @_resource = resource
  @_locals   = {}

  copy_instance_variables_from_context
end

Public Instance Methods

reset_for(resource) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 16
def reset_for(resource)
  @_resource = resource
  @_result = {}
end
result() click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 97
def result
  case RablRails.configuration.result_flags
  when 0
    @_result
  when 1
    @_result.each { |k, v| @_result[k] = ''.freeze if v == nil }
  when 2, 3
    @_result.each { |k, v| @_result[k] = nil if v == ''.freeze }
  when 4, 5
    @_result.delete_if { |_, v| v == nil }
  when 6
    @_result.delete_if { |_, v| v == nil || v == ''.freeze }
  end
end
visit_Attribute(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 21
def visit_Attribute n
  if !n.condition || instance_exec(_resource, &(n.condition))
    n.each { |k, v| @_result[k] = _resource.send(v) }
  end
end
visit_Child(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 27
def visit_Child n
  object = object_from_data(_resource, n)

  @_result[n.name] = if object
    collection?(object) ? object.map { |o| sub_visit(o, n.nodes) } : sub_visit(object, n.nodes)
  else
    nil
  end
end
visit_Code(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 54
def visit_Code n
  if !n.condition || instance_exec(_resource, &(n.condition))
    result = instance_exec _resource, &(n.block)

    if n.merge?
      raise RablRails::PartialError, '`merge` block should return a hash' unless result.is_a?(Hash)
      @_result.merge!(result)
    else
      @_result[n.name] = result
    end
  end
end
visit_Condition(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 80
def visit_Condition n
  @_result.merge!(sub_visit(_resource, n.nodes)) if instance_exec _resource, &(n.condition)
end
visit_Const(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 67
def visit_Const n
  @_result[n.name] = n.value
end
visit_Extend(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 84
def visit_Extend n
  @_locals = n.locals
  @_result.merge!(sub_visit(_resource, n.nodes))
ensure
  @_locals = {}
end
visit_Fetch(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 42
def visit_Fetch n
  hash   = object_from_data(_resource, n)
  key    = _resource.public_send(n.field)
  object = hash[key]

  @_result[n.name] = if object
    collection?(object) ? object.map { |o| sub_visit(o, n.nodes) } : sub_visit(object, n.nodes)
  else
    nil
  end
end
visit_Glue(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 37
def visit_Glue n
  object = object_from_data(_resource, n)
  @_result.merge!(sub_visit(object, n.nodes)) if object
end
visit_Lookup(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 71
def visit_Lookup n
  object  = object_from_data(_resource, n)
  key     = _resource.public_send(n.field)
  value   = object[key]
  value   = !!value if n.cast_to_boolean?

  @_result[n.name] = value
end
visit_Polymorphic(n) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 91
def visit_Polymorphic n
  template_path = n.template_lambda.call(_resource)
  template = RablRails::Library.instance.compile_template_from_path(template_path, @_context)
  @_result.merge!(sub_visit(_resource, template.nodes))
end

Protected Instance Methods

locals() click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 123
def locals
  @_locals
end
method_missing(name, *args, &block) click to toggle source

If a method is called inside a 'node' property or a 'if' lambda it will be passed to context if it exists or treated as a standard missing method.

Calls superclass method
# File lib/rabl-rails/visitors/to_hash.rb, line 119
def method_missing(name, *args, &block)
  @_context.respond_to?(name) ? @_context.send(name, *args, &block) : super
end
partial(template_path, options = {}) click to toggle source

Allow to use partial inside of node blocks (they are evaluated at rendering time).

# File lib/rabl-rails/visitors/to_hash.rb, line 131
def partial(template_path, options = {})
  raise RablRails::PartialError.new("No object was given to partial #{template_path}") unless options[:object]
  object = options[:object]
  @_locals = options[:locals].freeze

  return [] if object.respond_to?(:empty?) && object.empty?

  template = RablRails::Library.instance.compile_template_from_path(template_path, @_context)
  if object.respond_to?(:each)
    object.map { |o| sub_visit o, template.nodes }
  else
    sub_visit object, template.nodes
  end
ensure
  @_locals = {}
end

Private Instance Methods

copy_instance_variables_from_context() click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 150
def copy_instance_variables_from_context
  @_context.instance_variable_get(:@_assigns).each_pair { |k, v|
    instance_variable_set("@#{k}", v) unless k.to_s.start_with?('_'.freeze)
  }
end
object_from_data(resource, node) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 165
def object_from_data(resource, node)
  return resource if node.data == nil

  symbol = node.data
  if node.instance_variable_data?
    instance_variable_get(symbol)
  else
    resource.respond_to?(symbol) ? resource.send(symbol) : @_context.send(symbol)
  end
end
sub_visit(resource, nodes) click to toggle source
# File lib/rabl-rails/visitors/to_hash.rb, line 156
def sub_visit(resource, nodes)
  old_result, old_resource, @_result = @_result, @_resource, {}
  reset_for resource
  visit nodes
  result
ensure
  @_result, @_resource = old_result, old_resource
end