Class: HashSerializer

Inherits:
Object
  • Object
show all
Defined in:
app/serializers/hash_serializer.rb

Overview

Note:

Only use this with a json or jsonb back end column.

Serializes hashes for storage in a JSON/JSONB column, tolerating raw
String input (JSON or YAML, e.g. from an input form) on load and
returning values with indifferent access.

Class Method Summary collapse

Class Method Details

.dump(hash) ⇒ Hash?

Prepares a hash for database storage.

Parameters:

  • hash (Hash, nil)

    the value to store

Returns:

  • (Hash, nil)

    the value unchanged



13
14
15
# File 'app/serializers/hash_serializer.rb', line 13

def self.dump(hash)
  hash
end

.load(hash_raw) ⇒ Hash, Array

Restores a value read from the database, parsing JSON or YAML strings
and applying indifferent access to hashes.

Parameters:

  • hash_raw (Hash, Array, String, nil)

    the raw stored value

Returns:

  • (Hash, Array)

    the deserialized value (empty hash on nil/unparseable input)



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
# File 'app/serializers/hash_serializer.rb', line 22

def self.load(hash_raw)
  hash = nil
  if hash_raw.is_a?(String)
    hash_raw.strip

    # Try JSON first
    begin
      hash = JSON.parse(hash_raw, symbolize_names: true)
    rescue JSON::ParserError
      # Fall back to YAML
    end

    if hash.nil?
      # Try YAML (handles Ruby-style hash), this can come from an input form
      begin
        hash = YAML.safe_load(hash_raw, permitted_classes: [Symbol]) || {}
      rescue Psych::SyntaxError
        # nope
      end
    end
  elsif hash_raw.is_a?(Hash) || hash_raw.is_a?(Array)
    hash = hash_raw
  end

  # Default
  hash ||= {}
  # You might have an array which does not respond to with indifferent access
  if hash.is_a?(Array)
    hash.map { |v| v.respond_to?(:with_indifferent_access) ? v.with_indifferent_access : v }
  elsif hash.respond_to?(:with_indifferent_access)
    hash.with_indifferent_access
  else
    hash
  end
end