lib/simple_enum.rb in simple_enum-1.4.0 vs lib/simple_enum.rb in simple_enum-1.4.1
- old
+ new
@@ -13,10 +13,12 @@
require 'simple_enum/enum_hash'
require 'simple_enum/object_support'
require 'simple_enum/validation'
+require 'active_support/deprecation'
+
# Base module which gets included in <tt>ActiveRecord::Base</tt>. See documentation
# of +SimpleEnum::ClassMethods+ for more details.
module SimpleEnum
class << self
@@ -31,10 +33,12 @@
# * <tt>:upcase</tt> - If set to +true+ the <tt>Klass.foos</tt> is named <tt>Klass.FOOS</tt>, why? To better suite some
# coding-styles (default is +false+ => downcase)
# * <tt>:whiny</tt> - Boolean value which if set to <tt>true</tt> will throw an <tt>ArgumentError</tt>
# if an invalid value is passed to the setter (e.g. a value for which no enumeration exists). if set to
# <tt>false</tt> no exception is thrown and the internal value is set to <tt>nil</tt> (default is <tt>true</tt>)
+ # * <tt>:dirty</tt> - Boolean value which if set to <tt>true</tt> generates <tt>..._was</tt> and <tt>..._changed?</tt>
+ # methods for the enum, which delegate to the internal column.
def default_options
@default_options ||= {
:whiny => true,
:upcase => false
}
@@ -65,11 +69,11 @@
# end
#
# # or use a hash:
#
# class User < ActiveRecord::Base
- # as_enum :status, { :active => 1, :inactive => 0, :archived => 2, :deleted => 3 }, :column => 'status'
+ # as_enum :user_status, { :active => 1, :inactive => 0, :archived => 2, :deleted => 3 }, :column => 'status'
# end
#
# Now it's possible to access the enumeration and the internally stored value like:
#
# john_doe = User.new
@@ -147,13 +151,15 @@
# * <tt>:upcase</tt> - If set to +true+ the <tt>Klass.foos</tt> is named <tt>Klass.FOOS</tt>, why? To better suite some
# coding-styles (default is +false+ => downcase)
# * <tt>:whiny</tt> - Boolean value which if set to <tt>true</tt> will throw an <tt>ArgumentError</tt>
# if an invalid value is passed to the setter (e.g. a value for which no enumeration exists). if set to
# <tt>false</tt> no exception is thrown and the internal value is set to <tt>nil</tt> (default is <tt>true</tt>)
+ # * <tt>:dirty</tt> - Boolean value which if set to <tt>true</tt> generates <tt>..._was</tt> and <tt>..._changed?</tt>
+ # methods for the enum, which delegate to the internal column (default is <tt>false</tt>)
def as_enum(enum_cd, values, options = {})
options = SimpleEnum.default_options.merge({ :column => "#{enum_cd}_cd" }).merge(options)
- options.assert_valid_keys(:column, :whiny, :prefix, :slim, :upcase)
+ options.assert_valid_keys(:column, :whiny, :prefix, :slim, :upcase, :dirty)
metaclass = (class << self; self; end)
# convert array to hash...
values = SimpleEnum::EnumHash.new(values)
@@ -161,10 +167,13 @@
# store info away
self.enum_definitions = {} if self.enum_definitions.nil?
self.enum_definitions[enum_cd] = self.enum_definitions[options[:column]] = { :name => enum_cd, :column => options[:column], :options => options }
+ # display deprecation warning if enum_cd == column
+ ActiveSupport::Deprecation.warn "[simple_enum] use different names for #{enum_cd}'s name and column name (support for this will be dropped in 1.5)" if enum_cd.to_s == options[:column].to_s
+
# generate getter
define_method("#{enum_cd}") do
id = read_attribute options[:column]
values_inverted[id]
end
@@ -172,9 +181,20 @@
# generate setter
define_method("#{enum_cd}=") do |new_value|
v = new_value.blank? ? nil : values[new_value.to_sym]
raise(ArgumentError, "Invalid enumeration value: #{new_value}") if (options[:whiny] and v.nil? and !new_value.blank?)
write_attribute options[:column], v
+ end
+
+ # support dirty attributes by delegating to column, currently opt-in
+ if options[:dirty]
+ define_method("#{enum_cd}_changed?") do
+ self.send("#{options[:column]}_changed?")
+ end
+
+ define_method("#{enum_cd}_was") do
+ values_inverted[self.send("#{options[:column]}_was")]
+ end
end
# allow access to defined values hash, e.g. in a select helper or finder method.
attr_name = enum_cd.to_s.pluralize
enum_attr = :"#{attr_name.downcase}_enum_hash"