module HasMetadataColumn

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

Constants

TYPES

Valid values for the `:type` option.

Public Class Methods

metadata_typecast(value, type=nil) click to toggle source

@private

# File lib/has_metadata_column.rb, line 28
def self.metadata_typecast(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

Public Instance Methods

as_json(options={}) click to toggle source

@private

Calls superclass method
# 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.metadata_column]
  metadata          = self.class.metadata_column_fields.keys
  metadata          &= Array.wrap(options[:only]) if options[:only]
  metadata          -= Array.wrap(options[:except])
  options[:methods] = Array.wrap(options[:methods]) + metadata
  super options
end
assign_multiparameter_attributes(pairs) click to toggle source

@private

Calls superclass method
# File lib/has_metadata_column.rb, line 190
def assign_multiparameter_attributes(pairs)
  fake_attributes = pairs.select { |(field, _)| self.class.metadata_column_fields.include? field[0, field.index('(')].to_sym }

  fake_attributes.group_by { |(field, _)| field[0, field.index('(')] }.each do |field_name, parts|
    options = self.class.metadata_column_fields[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
inspect() click to toggle source

@private

# File lib/has_metadata_column.rb, line 220
def inspect
  "#<#{self.class.to_s} #{attributes.except(self.class.metadata_column.to_s).merge(_metadata_hash.try!(:stringify_keys) || {}).map { |k, v| "#{k}: #{v.inspect}" }.join(', ')}>"
end
reload(*) click to toggle source

@private

Calls superclass method
# File lib/has_metadata_column.rb, line 225
def reload(*)
  super.tap do
    @_metadata_hash = nil
  end
end
to_xml(options={}) click to toggle source

@private

Calls superclass method
# File lib/has_metadata_column.rb, line 180
def to_xml(options={})
  options[:except]  = Array.wrap(options[:except]) + [self.class.metadata_column]
  metadata          = self.class.metadata_column_fields.keys
  metadata          &= Array.wrap(options[:only]) if options[:only]
  metadata          -= Array.wrap(options[:except])
  options[:methods] = Array.wrap(options[:methods]) + metadata
  super options
end

Private Instance Methods

_metadata_hash() click to toggle source
# File lib/has_metadata_column.rb, line 233
def _metadata_hash
  @_metadata_hash ||= begin
    send(self.class.metadata_column) ? JSON.parse(send(self.class.metadata_column)) : {}
  rescue ActiveModel::MissingAttributeError
    {}
  end
end