Skip to content

Instantly share code, notes, and snippets.

@beerlington
Created June 15, 2014 13:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beerlington/0a986548f66822779eb8 to your computer and use it in GitHub Desktop.
Save beerlington/0a986548f66822779eb8 to your computer and use it in GitHub Desktop.
class ActiveEnumValue < Object
attr_reader :to_s
def initialize(option)
@to_s = option.to_s.downcase
end
end
module ActiveEnum
module ClassMethods
def new(option)
self::OPTION_HASH[option] || TypeError.new("Valid options are #{self.valid_options}")
end
def all
self::OPTIONS.map {|e| self.new(e) }
end
def valid_options
self::OPTIONS.map(&:to_s).join(', ')
end
end
def self.included(other)
other.extend ClassMethods
other.const_set("OPTION_HASH", Hash.new)
other::OPTIONS.each do |option|
klass = Class.new(ActiveEnumValue)
Object.const_set("#{other}#{option.to_s.camelize}", klass)
instance = klass.new(option)
other::OPTION_HASH[option] = instance
other::OPTION_HASH[option.to_s.downcase] = instance
ActiveEnum.const_set(option.to_s.upcase, instance)
end
end
end
# Use in active record classes where you want to create a method that returns an ActiveEnum object
# Example 1 - method and class are the same:
# active_enum_attr :priority
#
# Example 2 - method and class are different
# active_enum_attr :class_name, :method_name
module ActiveEnumAttributes
module ClassMethods
def active_enum_attr(klass, method=nil)
method ||= klass
self.instance_eval do
# Define getter method
define_method method do
klass.to_s.camelize.constantize.new super
end
# Define setter method
define_method "#{method}=" do |value|
super value.to_s
end
end
end
end
def self.included(other)
other.extend ClassMethods
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment