Module: MR::JsonField::ClassMethods

Defined in:
lib/mr/json_field.rb

Instance Method Summary collapse

Instance Method Details

#json_field(field_name, options = nil) ⇒ Object



40
41
42
43
# File 'lib/mr/json_field.rb', line 40

def json_field(field_name, options = nil)
  json_field_reader(field_name, options)
  json_field_writer(field_name, options)
end

#json_field_accessorsObject



118
119
120
# File 'lib/mr/json_field.rb', line 118

def json_field_accessors
  self.json_field_readers & self.json_field_writers
end

#json_field_reader(field_name, options = nil) ⇒ Object



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
70
71
72
73
74
75
76
77
78
79
# File 'lib/mr/json_field.rb', line 45

def json_field_reader(field_name, options = nil)
  options ||= {}
  field_name        = field_name.to_s
  ivar_name         = "@#{field_name}"
  source_field_name = (options[:source] || "#{field_name}_json").to_s

  if source_field_name == field_name
    raise ArgumentError, "the field name and source cannot be the same"
  end

  define_method(field_name) do
    if !(cached_value = self.instance_variable_get(ivar_name)).nil?
      return cached_value
    else
      source_value = self.send(source_field_name)
      return source_value if source_value.nil?

      value = begin
        MR::JsonField.decode(source_value)
      rescue InvalidJSONError => exception
        message = "can't decode `#{field_name}` JSON field (from " \
                  "`#{source_field_name}`): #{exception.message}"
        raise exception.class, message, caller
      end

      # cache the decoded value in the ivar
      self.instance_variable_set(ivar_name, value)

      value
    end
  end

  (self.json_field_readers       << field_name).uniq!
  (self.json_field_source_fields << source_field_name).uniq!
end

#json_field_readersObject



115
# File 'lib/mr/json_field.rb', line 115

def json_field_readers; @json_field_readers ||= []; end

#json_field_source_fieldsObject



122
123
124
# File 'lib/mr/json_field.rb', line 122

def json_field_source_fields
  @json_field_source_fields ||= []
end

#json_field_writer(field_name, options = nil) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/mr/json_field.rb', line 81

def json_field_writer(field_name, options = nil)
  options ||= {}
  field_name        = field_name.to_s.strip
  ivar_name         = "@#{field_name}"
  source_field_name = (options[:source] || "#{field_name}_json").to_s.strip

  if source_field_name == field_name
    raise ArgumentError, "the field name and source cannot be the same"
  end

  define_method("#{field_name}=") do |new_value|
    encoded_value = if !new_value.nil?
      begin
        MR::JsonField.encode(new_value)
      rescue InvalidJSONError => exception
        message = "can't encode value for `#{field_name}` JSON field: " \
                  "#{exception.message}"
        raise exception.class, message, caller
      end
    else
      nil
    end
    self.send("#{source_field_name}=", encoded_value)

    # reset the ivar so its value will be calculated again when read
    self.instance_variable_set(ivar_name, nil)

    new_value
  end

  (self.json_field_writers       << field_name).uniq!
  (self.json_field_source_fields << source_field_name).uniq!
end

#json_field_writersObject



116
# File 'lib/mr/json_field.rb', line 116

def json_field_writers; @json_field_writers ||= []; end