diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2013-08-30 16:48:20 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2013-08-30 16:48:20 -0700 |
commit | 74abdb1eab2dffea6247af7653b994c1f1bfe2ef (patch) | |
tree | 7fcbead76e4d42dad7485a2b41fda9237ac7d9a1 /activerecord/lib/active_record | |
parent | 1b84df430c324ff90b0a180039de0a345184ec94 (diff) | |
download | rails-74abdb1eab2dffea6247af7653b994c1f1bfe2ef.tar.gz rails-74abdb1eab2dffea6247af7653b994c1f1bfe2ef.tar.bz2 rails-74abdb1eab2dffea6247af7653b994c1f1bfe2ef.zip |
move the cache to the AR models and populate it on inherited
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/base.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/delegation.rb | 49 |
2 files changed, 31 insertions, 20 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index b06add096f..04e3dd49e7 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -18,6 +18,7 @@ require 'arel' require 'active_record/errors' require 'active_record/log_subscriber' require 'active_record/explain_subscriber' +require 'active_record/relation/delegation' module ActiveRecord #:nodoc: # = Active Record @@ -290,6 +291,7 @@ module ActiveRecord #:nodoc: extend Translation extend DynamicMatchers extend Explain + extend Delegation::DelegateCache include Persistence include ReadonlyAttributes diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb index 2b132d517d..31f924ba52 100644 --- a/activerecord/lib/active_record/relation/delegation.rb +++ b/activerecord/lib/active_record/relation/delegation.rb @@ -1,8 +1,33 @@ -require 'thread' -require 'thread_safe' +require 'active_support/concern' module ActiveRecord module Delegation # :nodoc: + module DelegateCache + def relation_delegate_class(klass) # :nodoc: + @relation_delegate_cache[klass] + end + + def initialize_relation_delegate_cache # :nodoc: + @relation_delegate_cache = cache = {} + [ + ActiveRecord::Relation, + ActiveRecord::Associations::CollectionProxy, + ActiveRecord::AssociationRelation + ].each do |klass| + delegate = Class.new(klass) { + include ActiveRecord::Relation::ClassSpecificRelation + } + const_set klass.name.gsub('::', '_'), delegate + cache[klass] = delegate + end + end + + def inherited(child_class) + child_class.initialize_relation_delegate_cache + super + end + end + extend ActiveSupport::Concern # This module creates compiled delegation methods dynamically at runtime, which makes @@ -71,30 +96,14 @@ module ActiveRecord end module ClassMethods # :nodoc: - @@subclasses = ThreadSafe::Cache.new(:initial_capacity => 2) - def create(klass, *args) relation_class_for(klass).new(klass, *args) end private - # Cache the constants in @@subclasses because looking them up via const_get - # make instantiation significantly slower. - def relation_class_for(klass) - klass_name = klass.name - - if klass_name - my_cache = @@subclasses.compute_if_absent(self) { ThreadSafe::Cache.new } - # This hash is keyed by klass.name to avoid memory leaks in development mode - my_cache.compute_if_absent(klass_name) do - # Cache#compute_if_absent guarantees that the block will only executed once for the given klass_name - subclass_name = "#{name.gsub('::', '_')}_#{klass_name.gsub('::', '_')}" - const_set(subclass_name, Class.new(self) { include ClassSpecificRelation }) - end - else - self - end + def relation_class_for(klass) + klass.relation_delegate_class(self) end end |