Class: Object

Inherits:
BasicObject
Defined in:
lib/safe_object_as_json.rb

Instance Method Summary collapse

Instance Method Details

#as_json(options = nil) ⇒ Object

Converts any object to JSON by creating a hash out of it’s instance variables. If there is a circular reference within an object hierarchy, then duplicate objects will be omitted in order to avoid infinite recursion.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/safe_object_as_json.rb', line 16

def as_json(options = nil)
  if respond_to?(:to_hash)
    to_hash.as_json(options)
  else
    # The default as_json serializer serializes the instance variables as name value pairs.
    # In order to prevent infinite recursion, we keep track of the object already used
    # in the serialization and omit them if they are included recursively.
    references = (Thread.current[:object_as_json_references] || Set.new)
    begin
      Thread.current[:object_as_json_references] = references if references.empty?
      references << object_id
      hash = {}

      # Apply :only and :except filter from the options to the hash of instance variables.
      values = instance_values
      if options && SafeObjectAsJson::SUPPORT_FILTERING
        only_attr = options[:only]
        if only_attr
          values = values.slice(*Array(only_attr).map(&:to_s))
        else
          except_attr = options[:except]
          if except_attr
            values = values.except(*Array(except_attr).map(&:to_s))
          end
        end
      end

      values.each do |name, value|
        unless references.include?(value.object_id) || value.is_a?(Proc) || value.is_a?(IO)
          references << value
          hash[name] = (options.nil? ? value.as_json : value.as_json(options.dup))
        end
      end
      hash
    ensure
      references.delete(object_id)
      Thread.current[:object_as_json_references] = nil if references.empty?
    end
  end
end