class NestedHstore::Serializer
Public Class Methods
new()
click to toggle source
# File lib/nested_hstore/serializer.rb, line 4 def initialize @type_key = '__TYPE__' @types_map = { array: '__ARRAY__', boolean: '__BOOLEAN__', float: '__FLOAT__', integer: '__INTEGER__', string: '__STRING__' } @types_map_inverted = @types_map.invert @value_key = '__VALUE__' end
Public Instance Methods
deserialize(hash)
click to toggle source
# File lib/nested_hstore/serializer.rb, line 44 def deserialize(hash) return nil if hash.nil? raise 'Hstore value should be a hash' unless hash.is_a?(Hash) type_value = hash.delete(@type_key) type = @types_map_inverted[type_value] deserialized = case type when :array hash.values.map { |v| decode_json_if_json(v) } when :boolean hash[@value_key] == 'true' when :float hash[@value_key].to_f when :integer hash[@value_key].to_i when :string hash[@value_key] else hash.each do |k, v| hash[k] = decode_json_if_json(v) end hash end deserialized end
serialize(value)
click to toggle source
# File lib/nested_hstore/serializer.rb, line 17 def serialize(value) return nil if value.nil? case value when Array type = :array hash = array_to_hash(value) when FalseClass, TrueClass type = :boolean hash = { @value_key => value } when Float type = :float hash = { @value_key => value } when Hash type = :hash hash = standardize_value(value) when Integer type = :integer hash = { @value_key => value } when String type = :string hash = { @value_key => value } else raise "Unsupported hstore type: #{value.class}" end hash_to_hstore(type, hash) end
Private Instance Methods
array_to_hash(array)
click to toggle source
# File lib/nested_hstore/serializer.rb, line 106 def array_to_hash(array) hash = {} array.each_with_index do |value, index| hash[index.to_s] = standardize_value(value) end hash end
decode_json_if_json(value)
click to toggle source
This isn’t ideal: how do we know whether each value in an hstore is JSON or a string/integer/etc?
# File lib/nested_hstore/serializer.rb, line 116 def decode_json_if_json(value) is_json = (value.start_with?('{') && value.end_with?('}')) || (value.start_with?('[') && value.end_with?(']')) return value unless is_json ActiveSupport::JSON.decode(value) rescue value end
encode_json(value)
click to toggle source
# File lib/nested_hstore/serializer.rb, line 125 def encode_json(value) ActiveSupport::JSON.encode(value) end
hash_to_hstore(type, hash)
click to toggle source
# File lib/nested_hstore/serializer.rb, line 71 def hash_to_hstore(type, hash) return {} if type == :hash && hash.blank? hstore = hash.dup hstore.each do |k, v| if v.is_a?(Array) || v.is_a?(Hash) hstore[k] = encode_json(v) else hstore[k] = v.to_s end end if type != :hash hstore.merge!(@type_key => @types_map[type]) end hstore end
standardize_value(value)
click to toggle source
# File lib/nested_hstore/serializer.rb, line 90 def standardize_value(value) if value.is_a?(Array) value.map! do |v| standardize_value(v) end elsif value.is_a?(Hash) value.each do |k, v| value[k] = standardize_value(v) end # Standardize Times to an ISO string, as that's what DateTime#to_s evaluates to elsif value.is_a?(Time) || value.is_a?(ActiveSupport::TimeWithZone) value = value.iso8601 end value end