Skip to content

Instantly share code, notes, and snippets.

@noelrappin
Created March 14, 2011 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noelrappin/869604 to your computer and use it in GitHub Desktop.
Save noelrappin/869604 to your computer and use it in GitHub Desktop.
# based on an idea by Gavin Mulligan
# http://gavin-mulligan.tumblr.com/post/3825225016/simple-rails-3-enumerations
# this version differs because
# * it returns StringInquirers rather than symbols,
# because I'll take any excuse to use StringInquirers
# * It uses meta program methods directly rather than class_eval
# * It auto-loads itself into ActiveRecord::Base
# * It supports a default option that uses default_value_for to set a default
#
# Usage:
# class Content < ActiveRecord::Base
# enumeration :state %w(draft for_approval approved published), :default => "draft"
# end
# c = Content.new
# c.state.draft?
# c.state.approved?
module EnumerationSupport
def enumeration(name, values, options = {})
const_name = name.to_s.pluralize.upcase
const_set(const_name, values.map{ |val| val.to_s })
validates name.to_sym, :presence => true,
:inclusion => {:in => const_get(const_name.to_sym),
:message => self.bad_enum_message(const_get(const_name.to_s))}
define_method name.to_sym do
::ActiveSupport::StringInquirer.new("#{read_attribute(name)}")
end
define_method :"#{name}=" do |value|
write_attribute name.to_sym, value.to_s
end
if options[:default].present?
default_value_for name.to_sym, options[:default].to_s
end
end
protected
def bad_enum_message(enum)
"is not in the set (#{enum.join(', ')})"
end
end
ActiveRecord::Base.send(:extend, EnumerationSupport)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment