Module: JsonSerialize::ClassMethods

Defined in:
lib/json_serialize.rb

Instance Method Summary collapse

Instance Method Details

#json_serialize(field, ..., fields_with_default_values) ⇒ Object

Marks one or more fields as JSON-serialized. These fields are stored in the database as JSON and encoded/decoded automatically upon read/write.

Parameters:

  • field (Symbol)

    The database field to JSON-serialize.

  • fields_with_default_values (Hash<Symbol, Object>)

    A map of additional fields to JSON-serialize, with the default value that should be given if the field is @NULL@.



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
69
# File 'lib/json_serialize.rb', line 21

def json_serialize(*fields)
  fields_with_defaults = fields.extract_options!
  fields.each do |field|
    fields_with_defaults[field] = nil
  end

  fields_with_defaults.each do |field, default_value|
    define_method field do
      if instance_variable_defined?(field_ivar(field)) then
        instance_variable_get field_ivar(field)
      else
        encoded = read_attribute(field)
        default = default_value.kind_of?(Proc) ? default_value.call : (default_value.duplicable? ? default_value.dup : default_value)
        decoded = encoded.nil? ? default : ActiveSupport::JSON.decode(encoded)
        instance_variable_set field_ivar(field), decoded
        decoded
      end
    end
  
    define_method :"#{field}=" do |value|
      write_attribute field, (value.nil? ? nil : ActiveSupport::JSON.encode(value))
      instance_variable_set field_ivar(field), value
    end
  end

  define_method :serialize_json_values do
    fields_with_defaults.keys.each do |field|
      if instance_variable_defined?(field_ivar(field)) then
        send :"#{field}=", instance_variable_get(field_ivar(field))
      end
    end
  end
  
  define_method :reload_with_refresh_json_ivars do |*args|
    res = reload_without_refresh_json_ivars *args
    fields_with_defaults.keys.each { |field| remove_instance_variable field_ivar(field) if instance_variable_defined?(field_ivar(field)) }
    res
  end
  
  define_method :update_with_refresh_json_ivars do |*args|
    res = update_without_refresh_json_ivars(*args)
    fields_with_defaults.keys.each { |field| remove_instance_variable field_ivar(field) if instance_variable_defined?(field_ivar(field)) }
    res
  end
  
  before_validation :serialize_json_values
  alias_method_chain :reload, :refresh_json_ivars
  alias_method_chain :update, :refresh_json_ivars
end