aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/aggregations.rb
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-03-02 21:24:56 +0000
committerJon Leighton <j@jonathanleighton.com>2011-03-04 09:30:27 +0000
commit735844db712c511dd8abf36a5279318fbc0ff9d0 (patch)
tree5fbd5d224ef85d8c878bf221db98b422c9345466 /activerecord/lib/active_record/aggregations.rb
parent9a98c766e045aebc2ef6d5b716936b73407f095d (diff)
parentb171b9e73dcc6a89b1da652da61c5127fe605b51 (diff)
downloadrails-735844db712c511dd8abf36a5279318fbc0ff9d0.tar.gz
rails-735844db712c511dd8abf36a5279318fbc0ff9d0.tar.bz2
rails-735844db712c511dd8abf36a5279318fbc0ff9d0.zip
Merge branch 'master' into nested_has_many_through
Conflicts: activerecord/CHANGELOG activerecord/lib/active_record/association_preload.rb activerecord/lib/active_record/associations.rb activerecord/lib/active_record/associations/class_methods/join_dependency.rb activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb activerecord/lib/active_record/associations/has_many_association.rb activerecord/lib/active_record/associations/has_many_through_association.rb activerecord/lib/active_record/associations/has_one_association.rb activerecord/lib/active_record/associations/has_one_through_association.rb activerecord/lib/active_record/associations/through_association_scope.rb activerecord/lib/active_record/reflection.rb activerecord/test/cases/associations/has_many_through_associations_test.rb activerecord/test/cases/associations/has_one_through_associations_test.rb activerecord/test/cases/reflection_test.rb activerecord/test/cases/relations_test.rb activerecord/test/fixtures/memberships.yml activerecord/test/models/categorization.rb activerecord/test/models/category.rb activerecord/test/models/member.rb activerecord/test/models/reference.rb activerecord/test/models/tagging.rb
Diffstat (limited to 'activerecord/lib/active_record/aggregations.rb')
-rw-r--r--activerecord/lib/active_record/aggregations.rb65
1 files changed, 21 insertions, 44 deletions
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index 8cd7389005..90d3b58c78 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -4,9 +4,7 @@ module ActiveRecord
extend ActiveSupport::Concern
def clear_aggregation_cache #:nodoc:
- self.class.reflect_on_all_aggregations.to_a.each do |assoc|
- instance_variable_set "@#{assoc.name}", nil
- end if self.persisted?
+ @aggregation_cache.clear if persisted?
end
# Active Record implements aggregation through a macro-like class method called +composed_of+
@@ -222,53 +220,32 @@ module ActiveRecord
private
def reader_method(name, class_name, mapping, allow_nil, constructor)
- module_eval do
- define_method(name) do |*args|
- force_reload = args.first || false
-
- unless instance_variable_defined?("@#{name}")
- instance_variable_set("@#{name}", nil)
- end
-
- if (instance_variable_get("@#{name}").nil? || force_reload) && (!allow_nil || mapping.any? {|pair| !read_attribute(pair.first).nil? })
- attrs = mapping.collect {|pair| read_attribute(pair.first)}
- object = case constructor
- when Symbol
- class_name.constantize.send(constructor, *attrs)
- when Proc, Method
- constructor.call(*attrs)
- else
- raise ArgumentError, 'Constructor must be a symbol denoting the constructor method to call or a Proc to be invoked.'
- end
- instance_variable_set("@#{name}", object)
- end
- instance_variable_get("@#{name}")
+ define_method(name) do
+ if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? {|pair| !read_attribute(pair.first).nil? })
+ attrs = mapping.collect {|pair| read_attribute(pair.first)}
+ object = constructor.respond_to?(:call) ?
+ constructor.call(*attrs) :
+ class_name.constantize.send(constructor, *attrs)
+ @aggregation_cache[name] = object
end
+ @aggregation_cache[name]
end
-
end
def writer_method(name, class_name, mapping, allow_nil, converter)
- module_eval do
- define_method("#{name}=") do |part|
- if part.nil? && allow_nil
- mapping.each { |pair| self[pair.first] = nil }
- instance_variable_set("@#{name}", nil)
- else
- unless part.is_a?(class_name.constantize) || converter.nil?
- part = case converter
- when Symbol
- class_name.constantize.send(converter, part)
- when Proc, Method
- converter.call(part)
- else
- raise ArgumentError, 'Converter must be a symbol denoting the converter method to call or a Proc to be invoked.'
- end
- end
-
- mapping.each { |pair| self[pair.first] = part.send(pair.last) }
- instance_variable_set("@#{name}", part.freeze)
+ define_method("#{name}=") do |part|
+ if part.nil? && allow_nil
+ mapping.each { |pair| self[pair.first] = nil }
+ @aggregation_cache[name] = nil
+ else
+ unless part.is_a?(class_name.constantize) || converter.nil?
+ part = converter.respond_to?(:call) ?
+ converter.call(part) :
+ class_name.constantize.send(converter, part)
end
+
+ mapping.each { |pair| self[pair.first] = part.send(pair.last) }
+ @aggregation_cache[name] = part.freeze
end
end
end