Module: HasMetadataColumn

Extended by:
ActiveSupport::Concern
Defined in:
lib/has_metadata_column.rb

Overview

Provides the ClassMethods#has_metadata_column method to subclasses of ‘ActiveRecord::Base`.

Defined Under Namespace

Modules: ClassMethods, Extensions

Constant Summary collapse

TYPES =

Valid values for the ‘:type` option.

[String, Integer, Float, Hash, Array, TrueClass, FalseClass, Boolean, NilClass, Date, Time]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.metadata_typecast(value, type = nil) ⇒ Object

Raises:

  • (ArgumentError)


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
# File 'lib/has_metadata_column.rb', line 28

def self.(value, type=nil)
  type ||= String
  raise ArgumentError, "Can't convert objects of type #{type.to_s}" unless TYPES.include?(type)

  if value.kind_of?(String) then
    if type == Integer then
      begin
        return Integer(value.sub(/^0+/, '')) # so that it doesn't think it's in octal
      rescue ArgumentError
        return value
      end
    elsif type == Float then
      begin
        return Float(value)
      rescue ArgumentError
        return value
      end
    elsif type == Boolean then
      return value.parse_bool
    elsif type == Date then
      return nil if value.nil?
      begin
        return Date.parse(value)
      rescue ArgumentError
        return value
      end
    elsif type == Time then
      return nil if value.nil?
      begin
        return Time.parse(value)
      rescue ArgumentError
        return value
      end
    end
  end
  return value
end

Instance Method Details

#as_json(options = {}) ⇒ Object



169
170
171
172
173
174
175
176
177
# File 'lib/has_metadata_column.rb', line 169

def as_json(options={})
  options           ||= Hash.new # the JSON encoder can sometimes give us nil options?
  options[:except]  = Array.wrap(options[:except]) + [self.class.]
            = self.class..keys
            &= Array.wrap(options[:only]) if options[:only]
            -= Array.wrap(options[:except])
  options[:methods] = Array.wrap(options[:methods]) + 
  super options
end

#assign_multiparameter_attributes(pairs) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/has_metadata_column.rb', line 190

def assign_multiparameter_attributes(pairs)
  fake_attributes = pairs.select { |(field, _)| self.class..include? field[0, field.index('(')].to_sym }

  fake_attributes.group_by { |(field, _)| field[0, field.index('(')] }.each do |field_name, parts|
    options = self.class.[field_name.to_sym]
    if options[:type] then
      args = parts.each_with_object([]) do |(part_name, value), ary|
        part_ann = part_name[part_name.index('(') + 1, part_name.length]
        index    = part_ann.to_i - 1
        raise "Out-of-bounds multiparameter argument index" unless index >= 0
        ary[index] = if value.blank? then
                       nil
                     elsif part_ann.ends_with?('i)') then
                       value.to_i
                     elsif part_ann.ends_with?('f)') then
                       value.to_f
                     else
                       value
                     end
      end
      send :"#{field_name}=", args.any? ? options[:type].new(*args) : nil
    else
      raise "#{field_name} has no type and cannot be used for multiparameter assignment"
    end
  end

  super(pairs.except(*fake_attributes.keys))
end

#inspectObject



220
221
222
# File 'lib/has_metadata_column.rb', line 220

def inspect
  "#<#{self.class.to_s} #{attributes.except(self.class..to_s).merge(.try!(:stringify_keys) || {}).map { |k, v| "#{k}: #{v.inspect}" }.join(', ')}>"
end

#reloadObject



225
226
227
228
229
# File 'lib/has_metadata_column.rb', line 225

def reload(*)
  super.tap do
    @_metadata_hash = nil
  end
end

#to_xml(options = {}) ⇒ Object



180
181
182
183
184
185
186
187
# File 'lib/has_metadata_column.rb', line 180

def to_xml(options={})
  options[:except]  = Array.wrap(options[:except]) + [self.class.]
            = self.class..keys
            &= Array.wrap(options[:only]) if options[:only]
            -= Array.wrap(options[:except])
  options[:methods] = Array.wrap(options[:methods]) + 
  super options
end