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