diff options
author | Mikel Lindsaar <raasdnil@gmail.com> | 2010-03-28 14:44:34 +1100 |
---|---|---|
committer | Mikel Lindsaar <raasdnil@gmail.com> | 2010-03-28 14:44:34 +1100 |
commit | 2bcc2ebf44b59e46c104c92d621e8051c97bfcf5 (patch) | |
tree | d2a3f04fd3020c1b5d88847af62d52f2d5e5bd61 /activemodel/lib | |
parent | f5774e3e3f70a3acfa559b9ff889e9417fb71d4b (diff) | |
parent | 8398f21880a952769ccd6437a4344922fe596dab (diff) | |
download | rails-2bcc2ebf44b59e46c104c92d621e8051c97bfcf5.tar.gz rails-2bcc2ebf44b59e46c104c92d621e8051c97bfcf5.tar.bz2 rails-2bcc2ebf44b59e46c104c92d621e8051c97bfcf5.zip |
Merge branch 'master' of git://github.com/rails/rails
Diffstat (limited to 'activemodel/lib')
-rw-r--r-- | activemodel/lib/active_model/attribute_methods.rb | 20 | ||||
-rw-r--r-- | activemodel/lib/active_model/callbacks.rb | 7 | ||||
-rw-r--r-- | activemodel/lib/active_model/dirty.rb | 35 | ||||
-rw-r--r-- | activemodel/lib/active_model/errors.rb | 3 | ||||
-rw-r--r-- | activemodel/lib/active_model/naming.rb | 2 | ||||
-rw-r--r-- | activemodel/lib/active_model/serializers/xml.rb | 7 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations.rb | 4 | ||||
-rw-r--r-- | activemodel/lib/active_model/validator.rb | 3 |
8 files changed, 48 insertions, 33 deletions
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 588976f1d4..f04829ef09 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -53,7 +53,6 @@ module ActiveModel 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 @@ -90,13 +89,20 @@ module ActiveModel # # => 'address_id' def define_attr_method(name, value=nil, &block) sing = singleton_class - sing.send :alias_method, "original_#{name}", name + 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 @@ -257,8 +263,13 @@ module ActiveModel 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 @@ -286,6 +297,7 @@ module ActiveModel end end + # Returns true if the attribute methods defined have been generated. def attribute_methods_generated? @attribute_methods_generated ||= nil end diff --git a/activemodel/lib/active_model/callbacks.rb b/activemodel/lib/active_model/callbacks.rb index a7e0cf90c1..d4e98de57b 100644 --- a/activemodel/lib/active_model/callbacks.rb +++ b/activemodel/lib/active_model/callbacks.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/array/wrap' require 'active_support/callbacks' module ActiveModel @@ -91,7 +92,7 @@ module ActiveModel options = callbacks.extract_options! options = { :terminator => "result == false", :scope => [:kind, :name] }.merge(options) - types = Array(options.delete(:only)) + types = Array.wrap(options.delete(:only)) types = [:before, :around, :after] if types.empty? callbacks.each do |callback| @@ -124,10 +125,10 @@ module ActiveModel def self.after_#{callback}(*args, &block) options = args.extract_options! options[:prepend] = true - options[:if] = Array(options[:if]) << "!halted && value != false" + options[:if] = Array.wrap(options[:if]) << "!halted && value != false" set_callback(:#{callback}, :after, *(args << options), &block) end CALLBACK end end -end
\ No newline at end of file +end diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 5f02929a9d..cb67ef7270 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -1,3 +1,5 @@ +require 'active_support/hash_with_indifferent_access' + module ActiveModel # <tt>ActiveModel::Dirty</tt> provides a way to track changes in your # object in the same way as ActiveRecord does. @@ -86,12 +88,17 @@ module ActiveModel attribute_method_affix :prefix => 'reset_', :suffix => '!' end + def initialize(*) + @changed_attributes = {} + super + end + # Do any attributes have unsaved changes? # person.changed? # => false # person.name = 'bob' # person.changed? # => true def changed? - !changed_attributes.empty? + !@changed_attributes.empty? end # List of attributes with unsaved changes. @@ -99,7 +106,7 @@ module ActiveModel # person.name = 'bob' # person.changed # => ['name'] def changed - changed_attributes.keys + @changed_attributes.keys end # Map of changed attrs => [original value, new value]. @@ -107,7 +114,7 @@ module ActiveModel # person.name = 'bob' # person.changes # => { 'name' => ['bill', 'bob'] } def changes - changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h } + changed.inject(HashWithIndifferentAccess.new){ |h, attr| h[attr] = attribute_change(attr); h } end # Map of attributes that were changed when the model was saved. @@ -116,33 +123,23 @@ module ActiveModel # person.save # person.previous_changes # => {'name' => ['bob, 'robert']} def previous_changes - previously_changed_attributes + @previously_changed end private - # Map of change <tt>attr => original value</tt>. - def changed_attributes - @changed_attributes ||= {} - end - - # Map of fields that were changed when the model was saved - def previously_changed_attributes - @previously_changed || {} - end - # Handle <tt>*_changed?</tt> for +method_missing+. def attribute_changed?(attr) - changed_attributes.include?(attr) + @changed_attributes.include?(attr) end # Handle <tt>*_change</tt> for +method_missing+. def attribute_change(attr) - [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr) + [@changed_attributes[attr], __send__(attr)] if attribute_changed?(attr) end # Handle <tt>*_was</tt> for +method_missing+. def attribute_was(attr) - attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) + attribute_changed?(attr) ? @changed_attributes[attr] : __send__(attr) end # Handle <tt>*_will_change!</tt> for +method_missing+. @@ -153,12 +150,12 @@ module ActiveModel rescue TypeError, NoMethodError end - changed_attributes[attr] = value + @changed_attributes[attr] = value end # Handle <tt>reset_*!</tt> for +method_missing+. def reset_attribute!(attr) - __send__("#{attr}=", changed_attributes[attr]) if attribute_changed?(attr) + __send__("#{attr}=", @changed_attributes[attr]) if attribute_changed?(attr) end end end diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index d8320275df..a9a54a90e0 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/string/inflections' require 'active_support/ordered_hash' @@ -206,7 +207,7 @@ module ActiveModel full_messages = [] each do |attribute, messages| - messages = Array(messages) + messages = Array.wrap(messages) next if messages.empty? if attribute == :base diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index 39512a427b..8cdd3d2fe8 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -1,6 +1,7 @@ require 'active_support/inflector' module ActiveModel + class Name < String attr_reader :singular, :plural, :element, :collection, :partial_path alias_method :cache_key, :collection @@ -57,4 +58,5 @@ module ActiveModel @_model_name ||= ActiveModel::Name.new(self) end end + end diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb index 86149f1e5f..c226359ea7 100644 --- a/activemodel/lib/active_model/serializers/xml.rb +++ b/activemodel/lib/active_model/serializers/xml.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/hash/conversions' @@ -85,8 +86,8 @@ module ActiveModel @options[:except] = Array.wrap(@options[:except]).map { |n| n.to_s } end - # To replicate the behavior in ActiveRecord#attributes, - # <tt>:except</tt> takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set + # To replicate the behavior in ActiveRecord#attributes, <tt>:except</tt> + # takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set # for a N level model but is set for the N+1 level models, # then because <tt>:except</tt> is set to a default value, the second # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if @@ -108,7 +109,7 @@ module ActiveModel end def serializable_method_attributes - Array(options[:methods]).inject([]) do |methods, name| + Array.wrap(options[:methods]).inject([]) do |methods, name| methods << MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s) methods end diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index ba8648f8c9..708557f4ae 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/hash/keys' require 'active_model/errors' @@ -112,11 +113,10 @@ module ActiveModel # end # end # - # This usage applies to +validate_on_create+ and +validate_on_update as well+. def validate(*args, &block) options = args.last if options.is_a?(Hash) && options.key?(:on) - options[:if] = Array(options[:if]) + options[:if] = Array.wrap(options[:if]) options[:if] << "@_on_validate == :#{options[:on]}" end set_callback(:validate, *args, &block) diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb index b61f0cb266..b7c52be3f0 100644 --- a/activemodel/lib/active_model/validator.rb +++ b/activemodel/lib/active_model/validator.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/array/wrap' require "active_support/core_ext/module/anonymous" module ActiveModel #:nodoc: @@ -130,7 +131,7 @@ module ActiveModel #:nodoc: # +options+ reader, however the <tt>:attributes</tt> option will be removed # and instead be made available through the +attributes+ reader. def initialize(options) - @attributes = Array(options.delete(:attributes)) + @attributes = Array.wrap(options.delete(:attributes)) raise ":attributes cannot be blank" if @attributes.empty? super check_validity! |