Class: JSI::JSICoder

Inherits:
Object
  • Object
show all
Defined in:
lib/jsi/jsi_coder.rb

Overview

this is an ActiveRecord serialization coder intended to serialize between JSON-compatible objects on the database side, and a JSI instance loaded on the model attribute.

on its own this coder is useful with a JSON database column. in order to serialize further to a string of JSON, or to YAML, the gem arms allows coders to be chained together. for example, for a table foos and a column preferences_json which is an actual json column, and preferences_txt which is a string:

Preferences = JSI.new_schema_module(preferences_json_schema)
class Foo < ActiveRecord::Base
  # as a single serializer, loads a Preferences instance from a json column
  serialize 'preferences_json', JSI::JSICoder.new(Preferences)

  # for a text column, arms_serialize will go from JSI to JSON-compatible
  # objects to a string. the symbol `:jsi` is a shortcut for JSI::JSICoder.
  arms_serialize 'preferences_txt', [:jsi, Preferences], :json
end

the column data may be either a single instance of the schema class (represented as one json object) or an array of them (represented as a json array of json objects), indicated by the keyword argument array.

Instance Method Summary collapse

Constructor Details

#initialize(schema, array: false, jsi_opt: {}) ⇒ JSICoder

Returns a new instance of JSICoder.

Parameters:

  • schema (#new_jsi)

    a Schema, SchemaSet, or JSI schema module. #load will instantiate column data using the JSI schemas represented.

  • array (Boolean) (defaults to: false)

    whether the dumped data represent one instance of the schema, or an array of them. note that it may be preferable to simply use an array schema.

  • jsi_opt (Hash) (defaults to: {})

    keyword arguments to pass to Schema#new_jsi when loading



33
34
35
36
37
38
39
40
# File 'lib/jsi/jsi_coder.rb', line 33

def initialize(schema, array: false, jsi_opt: {})
  unless schema.respond_to?(:new_jsi)
    raise(ArgumentError, "schema param does not respond to #new_jsi: #{schema.inspect}")
  end
  @schema = schema
  @array = array
  @jsi_opt = jsi_opt
end

Instance Method Details

#dump(object) ⇒ Object, ...

dumps the object for the database

Parameters:

  • object (JSI::Base, Array<JSI::Base>, nil)

    the JSI or array of JSIs containing the schema instance(s)

Returns:

  • (Object, Array, nil)

    the schema instance(s) of the JSI(s), or nil if object is nil



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/jsi/jsi_coder.rb', line 64

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

  if @array
    unless object.respond_to?(:to_ary)
      raise(TypeError, "expected array-like attribute; got: #{object.class}: #{object.inspect}")
    end
    object.to_ary.map do |el|
      dump_object(el)
    end
  else
    dump_object(object)
  end
end

#load(data) ⇒ JSI::Base, ...

loads the database column to JSI instances of our schema

Parameters:

  • data (Object, Array, nil)

    the dumped schema instance(s) of the JSI(s)

Returns:

  • (JSI::Base, Array<JSI::Base>, nil)

    the JSI or JSIs containing the schema instance(s), or nil if data is nil



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/jsi/jsi_coder.rb', line 47

def load(data)
  return nil if data.nil?

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