class Rabl::Builder
Constants
- SETTING_TYPES
Public Class Methods
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
# 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
# File lib/rabl/builder.rb, line 42 def replace_engine(engine, value) engines[engines.index(engine)] = value end
# 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
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
Evaluate conditions given a symbol/proc/lambda/variable to evaluate
# File lib/rabl/builder.rb, line 205 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
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 170 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
# 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
# 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
# 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 an existing rabl template with additional attributes in the block extends(“users/show”) { attribute :full_name }
# File lib/rabl/builder.rb, line 197 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
Glues data from a child node to the json_output glue(@user) { attribute :full_name => :user_full_name }
# File lib/rabl/builder.rb, line 187 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
# 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
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) 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
# 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
# File lib/rabl/builder.rb, line 88 def replace_empty_string_values @_result = deep_replace_empty_string_values(@_result) end
# File lib/rabl/builder.rb, line 73 def replace_nil_values @_result = deep_replace_nil_values(@_result) end
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 218 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
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 230 def attribute_present?(name) @_object.respond_to?(name) || (Rabl.configuration.raise_on_missing_attribute && raise("Failed to render missing attribute #{name}")) end
Caches the results of the block based on object cache_key cache_results
{ compile_hash(options) }
# File lib/rabl/builder.rb, line 246 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
# File lib/rabl/builder.rb, line 256 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
Returns a guess at the format in this context_scope request_format
=> “xml”
# File lib/rabl/builder.rb, line 238 def request_format format = @options[:format] format = "json" if !format || format == "hash" format end