Class: ARMS::StructCoder

Inherits:
Object
  • Object
show all
Defined in:
lib/arms/struct_coder.rb

Overview

this is a ActiveRecord serialization class intended to serialize from a Struct class on the loaded ruby side to something JSON-compatible on the dumped database side.

This coder relies on loaded_class, the Struct class which will be used to instantiate the column data. properties (members) of the loaded class will correspond to keys of the dumped json object.

the data may be either a single instance of the loaded class (serialized as one hash) or an array of them (serialized as an array of hashes), indicated by the boolean keyword argument array.

the column behind the attribute may be an actual JSON column (postgres json or jsonb - hstore should work too if you only have string attributes) or may be a string column with a string serializer after StructCoder.

Instance Method Summary collapse

Constructor Details

#initialize(loaded_class, array: false) ⇒ StructCoder

Returns a new instance of StructCoder.

Parameters:

  • loaded_class (Class)

    the Struct class to load

  • array (Boolean) (defaults to: false)

    whether the column holds an array of Struct instances instead of just one



19
20
21
22
23
24
25
26
# File 'lib/arms/struct_coder.rb', line 19

def initialize(loaded_class, array: false)
  @loaded_class = loaded_class
  # this notes the order of the keys as they were in the json, used by dump_object to generate
  # json that is equivalent to the json/jsonifiable that came in, so that AR's #changed_attributes
  # can tell whether the attribute has been changed.
  @loaded_class.send(:attr_accessor, :arms_object_json_coder_keys_order)
  @array = array
end

Instance Method Details

#dump(object) ⇒ Hash+

Parameters:

  • object (loaded_class, Array[loaded_class])

Returns:

  • (Hash, Array<Hash>)


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/arms/struct_coder.rb', line 45

def dump(object)
  return nil if object.nil?
  jsonifiable = begin
    if @array
      unless object.respond_to?(:to_ary)
        raise DumpError, "expected array-like attribute; got: #{object.class}: #{object.inspect}"
      end
      object.map do |el|
        dump_object(el)
      end
    else
      dump_object(object)
    end
  end
  jsonifiable
end

#load(data) ⇒ loaded_class, Array[loaded_class]

Parameters:

  • data (Hash, Array<Hash>)

Returns:

  • (loaded_class, Array[loaded_class])


30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/arms/struct_coder.rb', line 30

def load(data)
  return nil if data.nil?
  object = if @array
    unless data.respond_to?(:to_ary)
      raise LoadError, "expected array-like column data; got: #{data.class}: #{data.inspect}"
    end
    data.map { |el| load_object(el) }
  else
    load_object(data)
  end
  object
end