class Rabl::Builder

Constants

SETTING_TYPES

Public Class Methods

new(object, settings = {}, options = {}) click to toggle source

Constructs a new rabl hash based on given object and options options = { :format => “json”, :root => true, :child_root => true,

:attributes, :node, :child, :glue, :extends }
# File lib/rabl/builder.rb, line 20
def initialize(object, settings = {}, options = {})
  @_object = object

  @settings       = settings
  @options        = options
  @_context_scope = options[:scope]
  @_view_path     = options[:view_path]
end

Public Instance Methods

engines() click to toggle source
# File lib/rabl/builder.rb, line 29
def engines
  return @_engines if defined?(@_engines)

  @_engines = []

  # Append onto @_engines
  compile_settings(:extends)
  compile_settings(:child)
  compile_settings(:glue)

  @_engines
end
replace_engine(engine, value) click to toggle source
# File lib/rabl/builder.rb, line 42
def replace_engine(engine, value)
  engines[engines.index(engine)] = value
end
to_hash(object = nil, settings = nil, options = nil) click to toggle source
# File lib/rabl/builder.rb, line 46
def to_hash(object = nil, settings = nil, options = nil)
  @_object = object           if object
  @options.merge!(options)    if options
  @settings.merge!(settings)  if settings

  cache_results do
    @_result = {}

    # Merges directly into @_result
    compile_settings(:attributes)

    merge_engines_into_result

    # Merges directly into @_result
    compile_settings(:node)

    replace_nil_values          if Rabl.configuration.replace_nil_values_with_empty_strings
    replace_empty_string_values if Rabl.configuration.replace_empty_string_values_with_nil_values
    remove_nil_values           if Rabl.configuration.exclude_nil_values

    result = @_result
    result = { @options[:root_name] => result } if @options[:root_name].present?
    result
  end
end

Protected Instance Methods

attribute(name, options = {}) click to toggle source

Indicates an attribute or method should be included in the json output attribute :foo, :as => “bar” attribute :foo, :as => “bar”, :if => lambda { |m| m.foo }

# File lib/rabl/builder.rb, line 139
def attribute(name, options = {})
  return unless
    @_object &&
    attribute_present?(name) &&
    resolve_condition(options)

  attribute = data_object_attribute(name)
  name = create_key(options[:as] || name)
  @_result[name] = attribute
end
Also aliased as: attributes
attributes(name, options = {})
Alias for: attribute
call_condition_proc(condition, object) click to toggle source

Evaluate conditions given a symbol/proc/lambda/variable to evaluate

# File lib/rabl/builder.rb, line 206
def call_condition_proc(condition, object)
  case condition
  when Proc   then condition.call(object)
  when Symbol then condition.to_proc.call(object)
  else             condition
  end
end
child(data, options = {}, &block) click to toggle source

Creates a child node that is included in json output child(@user) { attribute :full_name } child(@user => :person) { … } child(@users => :people) { … }

# File lib/rabl/builder.rb, line 171
def child(data, options = {}, &block)
  return unless data.present? && resolve_condition(options)

  name   = is_name_value?(options[:root]) ? options[:root] : data_name(data)
  object = data_object(data)

  engine_options = @options.slice(:child_root)
  engine_options[:root] = is_collection?(object) && options.fetch(:object_root, @options[:child_root]) # child @users
  engine_options[:object_root_name] = options[:object_root] if is_name_value?(options[:object_root])

  object = { object => name } if data.is_a?(Hash) && object # child :users => :people

  engines << { create_key(name) => object_to_engine(object, engine_options, &block) }
end
code(name, options = {}, &block)
Alias for: node
compile_settings(type) click to toggle source
# File lib/rabl/builder.rb, line 111
def compile_settings(type)
  return unless @settings.has_key?(type)

  settings_type = SETTING_TYPES[type]
  @settings[type].each do |setting|
    send(type, setting[settings_type], setting[:options] || {}, &setting[:block])
  end
end
deep_replace_empty_string_values(hash) click to toggle source
# File lib/rabl/builder.rb, line 92
def deep_replace_empty_string_values(hash)
  hash.inject({}) do |new_hash, (k, v)|
    new_hash[k] = if v.is_a?(Hash)
      deep_replace_empty_string_values(v)
    else
      (!v.nil? && v != "") ? v : nil
    end

    new_hash
  end
end
deep_replace_nil_values(hash) click to toggle source
# File lib/rabl/builder.rb, line 77
def deep_replace_nil_values(hash)
  hash.inject({}) do |new_hash, (k, v)|
    new_hash[k] = if v.is_a?(Hash)
      deep_replace_nil_values(v)
    else
      v.nil? ? '' : v
    end
    new_hash
  end
end
extends(file, options = {}, &block) click to toggle source

Extends an existing rabl template with additional attributes in the block extends(“users/show”) { attribute :full_name }

# File lib/rabl/builder.rb, line 198
def extends(file, options = {}, &block)
  return unless resolve_condition(options)

  options = @options.slice(:child_root).merge!(:object => @_object).merge!(options)
  engines << partial_as_engine(file, options, &block)
end
glue(data, options = {}, &block) click to toggle source

Glues data from a child node to the json_output glue(@user) { attribute :full_name => :user_full_name }

# File lib/rabl/builder.rb, line 188
def glue(data, options = {}, &block)
  return unless data.present? && resolve_condition(options)

  object = data_object(data)
  engine = object_to_engine(object, :root => false, &block)
  engines << engine if engine
end
merge_engines_into_result() click to toggle source
# File lib/rabl/builder.rb, line 120
def merge_engines_into_result
  engines.each do |engine|
    case engine
    when Hash
      # engine was stored in the form { name => #<Engine> }
      engine.each do |key, value|
        engine[key] = value.render if value.is_a?(Engine)
      end
    when Engine
      engine = engine.render
    end

    @_result.merge!(engine) if engine.is_a?(Hash)
  end
end
node(name, options = {}, &block) click to toggle source

Creates an arbitrary node that is included in the json output node(:foo) { “bar” } node(:foo, :if => lambda { |m| m.foo.present? }) { “bar” }

# File lib/rabl/builder.rb, line 154
def node(name, options = {}, &block)
  return unless resolve_condition(options)
  return if @options.has_key?(:except) && [@options[:except]].flatten.include?(name)

  result = block.call(@_object)
  if name.present?
    @_result[create_key(name)] = result
  elsif result.is_a?(Hash) # merge hash into root hash
    @_result.merge!(result)
  end
end
Also aliased as: code
remove_nil_values() click to toggle source
# File lib/rabl/builder.rb, line 104
def remove_nil_values
  @_result = @_result.inject({}) do |new_hash, (k, v)|
    new_hash[k] = v unless v.nil?
    new_hash
  end
end
replace_empty_string_values() click to toggle source
# File lib/rabl/builder.rb, line 88
def replace_empty_string_values
  @_result = deep_replace_empty_string_values(@_result)
end
replace_nil_values() click to toggle source
# File lib/rabl/builder.rb, line 73
def replace_nil_values
  @_result = deep_replace_nil_values(@_result)
end
resolve_condition(options) click to toggle source

resolve_condition(:if => true) => true resolve_condition(:if => ‘Im truthy’) => true resolve_condition(:if => lambda { |m| false }) => false resolve_condition(:unless => lambda { |m| false }) => true resolve_condition(:unless => lambda { |m| false }, :if => proc { true}) => true

# File lib/rabl/builder.rb, line 219
def resolve_condition(options)
  result = true
  result &&=  call_condition_proc(options[:if], @_object)     if
    options.key?(:if)
  result &&= !call_condition_proc(options[:unless], @_object) if
    options.key?(:unless)
  result
end

Private Instance Methods

attribute_present?(name) click to toggle source

Checks if an attribute is present. If not, check if the configuration specifies that this is an error attribute_present?(created_at) => true

# File lib/rabl/builder.rb, line 231
def attribute_present?(name)
  @_object.respond_to?(name) ||
    (Rabl.configuration.raise_on_missing_attribute &&
     raise("Failed to render missing attribute #{name}"))
end
cache_results() { || ... } click to toggle source

Caches the results of the block based on object cache_key cache_results { compile_hash(options) }

# File lib/rabl/builder.rb, line 247
def cache_results(&block)
  if template_cache_configured? && Rabl.configuration.cache_all_output && @_object.respond_to?(:cache_key)
    cache_key = [@_object, @options[:root_name], @options[:format]]

    fetch_result_from_cache(cache_key, &block)
  else # skip cache
    yield
  end
end
create_key(name) click to toggle source
# File lib/rabl/builder.rb, line 257
def create_key(name)
  if Rabl.configuration.camelize_keys
    name.to_s.camelize(Rabl.configuration.camelize_keys == :upper ? :upper : :lower).to_sym
  else
    name.to_sym
  end
end
request_format() click to toggle source

Returns a guess at the format in this context_scope request_format => “xml”

# File lib/rabl/builder.rb, line 239
def request_format
  format = @options[:format]
  format = "json" if !format || format == "hash"
  format
end