lib/active_model/attribute_methods.rb in activemodel-3.0.0.beta vs lib/active_model/attribute_methods.rb in activemodel-3.0.0.beta2

- old
+ new

@@ -19,11 +19,10 @@ # * Define the various generic +_attribute+ methods that you have declared # # A minimal implementation could be: # # class Person - # # include ActiveModel::AttributeMethods # # attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!' # attribute_method_suffix '_contrived?' # attribute_method_prefix 'clear_' @@ -42,17 +41,20 @@ # end # # def reset_attribute_to_default!(attr) # send("#{attr}=", "Default Name") # end - # # end - # + # + # Please notice that whenever you include ActiveModel::AtributeMethods in your class, + # it requires you to implement a <tt>attributes</tt> methods which returns a hash with + # each attribute name in your model as hash key and the attribute value as hash value. + # Hash keys must be a string. + # module AttributeMethods extend ActiveSupport::Concern - # Declare and check for suffixed attribute methods. module ClassMethods # Defines an "attribute" method (like +inheritance_column+ or # +table_name+). A new (class) method will be created with the # given name. If a value is specified, the new method will # return that value (as a string). Otherwise, the given block @@ -84,18 +86,25 @@ # # => "sysid" # AttributePerson.inheritance_column = 'address' # AttributePerson.inheritance_column # # => 'address_id' def define_attr_method(name, value=nil, &block) - sing = metaclass - sing.send :alias_method, "original_#{name}", name + sing = singleton_class + sing.class_eval <<-eorb, __FILE__, __LINE__ + 1 + if method_defined?(:original_#{name}) + undef :original_#{name} + end + alias_method :original_#{name}, :#{name} + eorb if block_given? sing.send :define_method, name, &block else # use eval instead of a block to work around a memory leak in dev # mode in fcgi - sing.class_eval "def #{name}; #{value.to_s.inspect}; end" + sing.class_eval <<-eorb, __FILE__, __LINE__ + 1 + def #{name}; #{value.to_s.inspect}; end + eorb end end # Declares a method available for all attributes with the given prefix. # Uses +method_missing+ and <tt>respond_to?</tt> to rewrite the method. @@ -252,12 +261,17 @@ generate_method = "define_method_#{matcher.prefix}attribute#{matcher.suffix}" if respond_to?(generate_method) send(generate_method, attr_name) else + method_name = matcher.method_name(attr_name) + generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__+1 - def #{matcher.method_name(attr_name)}(*args) + if method_defined?(:#{method_name}) + undef :#{method_name} + end + def #{method_name}(*args) send(:#{matcher.method_missing_target}, '#{attr_name}', *args) end STR end end @@ -281,9 +295,10 @@ include mod mod end end + # Returns true if the attribute methods defined have been generated. def attribute_methods_generated? @attribute_methods_generated ||= nil end protected