module MetaField

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def meta_field(field, options={})
      type = options.fetch(:type, String)
      required = options.fetch(:required, false)
      default = options.fetch(:default, nil)

      self.send(:validates_presence_of, field) if required

      define_method field do
        self.metadata[field]
      end

      define_method "#{field}=" do |value|
        self.metadata[field] = Kernel.const_get(type.to_s.classify).new(value || default)
      end
    end
  end

  def metadata
    self.read_attribute(:metadata) || {}
  end
end