Permalink
Switch branches/tags
Find file
Fetching contributors…
Cannot retrieve contributors at this time
72 lines (61 sloc) 2.31 KB
require "active_record"
# See the enum class level method for more info.
module Enumlogic
# Allows you to easily specify enumerations for your models. Specify enumerations like:
#
# class Computer < ActiveRecord::Base
# enum :kind, ["apple", "dell", "hp"]
# # or....
# enum :kind, {"apple" => "Apple", "dell" => "Dell", "hp" => "HP"}
# end
#
# You can now do the following:
#
# Computer::KINDS # passes back the defined enum keys as array
# Computer.kind_options # gives you a friendly hash that you can easily pass into the select helper for forms
# Computer.new(:kind => "unknown").valid? # false, automatically validates inclusion of the enum field
#
# c = Computer.new(:kind => "apple")
# c.kind_apple? # true, or c.apple? if :namespace => false
# c.kind_key # :apple
# c.kind_text # "apple" or "Apple" if you gave a hash with a user friendly text value
# c.enum?(:kind) # true
def enum(field, values, options = {})
namespace = options.key?(:namespace) ? options[:namespace] : true
values_hash = if values.is_a?(Array)
hash = {}
values.each { |value| hash[value] = value }
hash
else
values
end
values_array = values.is_a?(Hash) ? values.keys : values
constant_name = options[:constant] || field.to_s.pluralize.upcase
const_set constant_name, values_array unless const_defined?(constant_name)
new_hash = {}
values_hash.each { |key, text| new_hash[text] = key }
(class << self; self; end).send(:define_method, "#{field}_options") { new_hash }
define_method("#{field}_key") do
value = send(field)
return nil if value.nil?
value.to_s.gsub(/[-\s]/, '_').downcase.to_sym
end
define_method("#{field}_text") do
value = send(field)
return nil if value.nil?
values_hash[value]
end
values_array.each do |value|
method_name = value.underscore.gsub(/[-\s]/, '_')
method_name = "#{field}_#{method_name}" if namespace
define_method("#{method_name}?") do
self.send(field) == value
end
end
validates_inclusion_of field, :in => values_array, :message => options[:message], :allow_nil => options[:allow_nil], :if => options[:if]
end
def enum?(name)
method_defined?("#{name}_key")
end
end
ActiveRecord::Base.extend(Enumlogic)