Module: Respondo::Serializer

Defined in:
lib/respondo/serializer.rb

Overview

Responsible for converting any Ruby object into a JSON-safe Hash or Array.

Priority order:

1. Custom serializer from Respondo.config (if set)
2. ActiveRecord::Base / ActiveRecord::Relation
3. ActiveModel::Errors / objects responding to #errors
4. Objects responding to #as_json or #to_h
5. Arrays — each element is serialized recursively
6. Primitives — returned as-is

Class Method Summary collapse

Class Method Details

.active_model_errors?(object) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/respondo/serializer.rb', line 84

def active_model_errors?(object)
  defined?(ActiveModel::Errors) &&
    object.is_a?(ActiveModel::Errors)
end

.ar_model?(object) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
82
# File 'lib/respondo/serializer.rb', line 79

def ar_model?(object)
  defined?(ActiveRecord::Base) &&
    object.is_a?(ActiveRecord::Base)
end

.ar_relation?(object) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
77
# File 'lib/respondo/serializer.rb', line 74

def ar_relation?(object)
  defined?(ActiveRecord::Relation) &&
    object.is_a?(ActiveRecord::Relation)
end

.call(object) ⇒ Hash, ...

Parameters:

  • object (Object)

    anything — AR model, collection, error, hash, array, primitive

Returns:

  • (Hash, Array, String, Numeric, nil)


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
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/respondo/serializer.rb', line 18

def call(object)
  return nil if object.nil?

  # 1. Custom serializer wins
  if Respondo.config.serializer
    return Respondo.config.serializer.call(object)
  end

  # 2. ActiveRecord::Relation or any object with #map (lazy collections)
  if ar_relation?(object)
    return object.map { |record| serialize_record(record) }
  end

  # 3. Array — recurse
  if object.is_a?(Array)
    return object.map { |item| call(item) }
  end

  # 4. ActiveRecord model instance
  if ar_model?(object)
    return serialize_record(object)
  end

  # 5. ActiveModel::Errors object
  if active_model_errors?(object)
    return serialize_errors(object)
  end

  # 6. Exception / StandardError
  if object.is_a?(Exception)
    return { message: object.message }
  end

  # 7. Hash — recursively serialize values
  if object.is_a?(Hash)
    return object.transform_values { |v| call(v) }
  end

  # 8. Responds to #as_json (ActiveSupport)
  if object.respond_to?(:as_json)
    return object.as_json
  end

  # 9. Responds to #to_h
  if object.respond_to?(:to_h)
    return object.to_h
  end

  # 10. Primitive — return as-is
  object
end

.serialize_errors(errors) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/respondo/serializer.rb', line 99

def serialize_errors(errors)
  # ActiveModel::Errors — return { field: ["msg", ...] }
  if errors.respond_to?(:to_hash)
    errors.to_hash
  elsif errors.respond_to?(:messages)
    errors.messages
  else
    {}
  end
end

.serialize_record(record) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'lib/respondo/serializer.rb', line 89

def serialize_record(record)
  if record.respond_to?(:as_json)
    record.as_json
  elsif record.respond_to?(:to_h)
    record.to_h
  else
    record
  end
end