diff --git a/active_model_serializers.gemspec b/active_model_serializers.gemspec index 2ad4ee54..39b8ba2a 100644 --- a/active_model_serializers.gemspec +++ b/active_model_serializers.gemspec @@ -21,5 +21,6 @@ Gem::Specification.new do |gem| gem.required_ruby_version = ">= 1.9.3" gem.add_dependency "activemodel", ">= 3.2" + gem.add_dependency "concurrent-ruby", "~> 1.0" gem.add_development_dependency "rails", ">= 3.2" end diff --git a/lib/active_model/serializable.rb b/lib/active_model/serializable.rb index 344d8e4e..d23aae7d 100644 --- a/lib/active_model/serializable.rb +++ b/lib/active_model/serializable.rb @@ -33,7 +33,11 @@ module ActiveModel end def namespace - get_namespace && Utils._const_get(get_namespace) + if module_name = get_namespace + Serializer.serializers_cache.fetch_or_store(module_name) do + Utils._const_get(module_name) + end + end end def embedded_in_root_associations diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 82693873..a89a79a8 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -4,6 +4,7 @@ require 'active_model/serializer/association' require 'active_model/serializer/config' require 'thread' +require 'concurrent/map' module ActiveModel class Serializer @@ -65,7 +66,10 @@ end ArraySerializer end else - _const_get build_serializer_class(resource, options) + klass_name = build_serializer_class(resource, options) + Serializer.serializers_cache.fetch_or_store(klass_name) do + _const_get(klass_name) + end end end @@ -100,6 +104,10 @@ end associate(Association::HasMany, *attrs) end + def serializers_cache + @serializers_cache ||= Concurrent::Map.new + end + private def strip_attribute(attr) diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb index 7066ebf4..8b50eb55 100644 --- a/lib/active_model_serializers.rb +++ b/lib/active_model_serializers.rb @@ -14,6 +14,9 @@ begin ActionController::Base.send(:include, ::ActionController::Serialization) ActionController::TestCase.send(:include, ::ActionController::SerializationAssertions) end + ActionDispatch::Reloader.to_prepare do + ActiveModel::Serializer.serializers_cache.clear + end end rescue LoadError # rails not installed, continuing