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"