From 7fcc8c0a1f38c77b12cb6ffe81fb2887e6c60b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 23 Nov 2011 23:45:27 +0000 Subject: Rely solely on active_model_serializer and remove the fancy constant lookup. --- .../lib/action_controller/metal/serialization.rb | 4 +- actionpack/test/controller/render_json_test.rb | 16 +++++++- activemodel/lib/active_model/serializable.rb | 12 +++--- activemodel/lib/active_model/serializer.rb | 45 ++++------------------ activemodel/test/cases/serializer_test.rb | 37 ++---------------- activesupport/lib/active_support/dependencies.rb | 1 + activesupport/test/class_cache_test.rb | 5 +++ 7 files changed, 41 insertions(+), 79 deletions(-) diff --git a/actionpack/lib/action_controller/metal/serialization.rb b/actionpack/lib/action_controller/metal/serialization.rb index 9bb665a9ae..9fb49f512e 100644 --- a/actionpack/lib/action_controller/metal/serialization.rb +++ b/actionpack/lib/action_controller/metal/serialization.rb @@ -13,7 +13,9 @@ module ActionController end def _render_option_json(json, options) - json = json.active_model_serializer.new(json, serialization_scope) if json.respond_to?(:active_model_serializer) + if json.respond_to?(:active_model_serializer) && (serializer = json.active_model_serializer) + json = serializer.new(json, serialization_scope) + end super end diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb index f886af1a95..dc09812ba3 100644 --- a/actionpack/test/controller/render_json_test.rb +++ b/actionpack/test/controller/render_json_test.rb @@ -26,8 +26,12 @@ class RenderJsonTest < ActionController::TestCase end class JsonSerializable + def initialize(skip=false) + @skip = skip + end + def active_model_serializer - JsonSerializer + JsonSerializer unless @skip end def as_json(*) @@ -89,6 +93,11 @@ class RenderJsonTest < ActionController::TestCase @current_user = Struct.new(:as_json).new(:current_user => true) render :json => JsonSerializable.new end + + def render_json_with_serializer_api_but_without_serializer + @current_user = Struct.new(:as_json).new(:current_user => true) + render :json => JsonSerializable.new(true) + end end tests TestController @@ -166,4 +175,9 @@ class RenderJsonTest < ActionController::TestCase assert_match '"scope":{"current_user":true}', @response.body assert_match '"object":{"serializable_object":true}', @response.body end + + def test_render_json_with_serializer_api_but_without_serializer + get :render_json_with_serializer_api_but_without_serializer + assert_match '{"serializable_object":true}', @response.body + end end diff --git a/activemodel/lib/active_model/serializable.rb b/activemodel/lib/active_model/serializable.rb index 769e934dbe..70e27c5683 100644 --- a/activemodel/lib/active_model/serializable.rb +++ b/activemodel/lib/active_model/serializable.rb @@ -1,6 +1,7 @@ require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/string/inflections' module ActiveModel # == Active Model Serializable @@ -72,11 +73,10 @@ module ActiveModel autoload :JSON, "active_model/serializable/json" autoload :XML, "active_model/serializable/xml" - include ActiveModel::Serializer::Scope - module ClassMethods #:nodoc: - def _model_serializer - @_model_serializer ||= ActiveModel::Serializer::Finder.find(self, self) + def active_model_serializer + return @active_model_serializer if defined?(@active_model_serializer) + @active_model_serializer = "#{self.name}Serializer".safe_constantize end end @@ -108,8 +108,8 @@ module ActiveModel end # Returns a model serializer for this object considering its namespace. - def model_serializer - self.class._model_serializer + def active_model_serializer + self.class.active_model_serializer end private diff --git a/activemodel/lib/active_model/serializer.rb b/activemodel/lib/active_model/serializer.rb index a541a1053d..5478da15c8 100644 --- a/activemodel/lib/active_model/serializer.rb +++ b/activemodel/lib/active_model/serializer.rb @@ -1,7 +1,6 @@ require "active_support/core_ext/class/attribute" require "active_support/core_ext/string/inflections" require "active_support/core_ext/module/anonymous" -require "active_support/core_ext/module/introspection" require "set" module ActiveModel @@ -15,7 +14,7 @@ module ActiveModel def serializable_array @object.map do |item| - if serializer = Serializer::Finder.find(item, scope) + if item.respond_to?(:active_model_serializer) && (serializer = item.active_model_serializer) serializer.new(item, scope) else item @@ -30,41 +29,6 @@ module ActiveModel # Active Model Serializer class Serializer - module Finder - mattr_accessor :constantizer - @@constantizer = ActiveSupport::Inflector - - # Finds a serializer for the given object in the given scope. - # If the object implements a +model_serializer+ method, it does - # not do a scope lookup but uses the model_serializer method instead. - def self.find(object, scope) - if object.respond_to?(:model_serializer) - object.model_serializer - else - scope = scope.class unless scope.respond_to?(:const_defined?) - object = object.class unless object.respond_to?(:name) - serializer = "#{object.name.demodulize}Serializer" - - begin - scope.const_get serializer - rescue NameError => e - raise unless e.message =~ /uninitialized constant ([\w_]+::)*#{serializer}$/ - scope.parents.each do |parent| - return parent.const_get(serializer) if parent.const_defined?(serializer) - end - nil - end - end - end - end - - # Defines the serialization scope. Core extension serializers - # are defined in this module so a scoped lookup is able to find - # core extension serializers. - module Scope - ArraySerializer = ::ActiveModel::ArraySerializer - end - module Associations class Config < Struct.new(:name, :options) def serializer @@ -216,3 +180,10 @@ module ActiveModel end end end + +class Array + # Array uses ActiveModel::ArraySerializer. + def active_model_serializer + ActiveModel::ArraySerializer + end +end \ No newline at end of file diff --git a/activemodel/test/cases/serializer_test.rb b/activemodel/test/cases/serializer_test.rb index e99b3692ec..f6c4282d39 100644 --- a/activemodel/test/cases/serializer_test.rb +++ b/activemodel/test/cases/serializer_test.rb @@ -19,10 +19,8 @@ class SerializerTest < ActiveModel::TestCase include ActiveModel::Serializable attr_accessor :superuser - attr_writer :model_serializer def initialize(hash={}) - @model_serializer = nil @attributes = hash.merge(:first_name => "Jose", :last_name => "Valim", :password => "oh noes yugive my password") end @@ -33,17 +31,15 @@ class SerializerTest < ActiveModel::TestCase def super_user? @superuser end - - def model_serializer - @model_serializer || super - end end class Post < Model attr_accessor :comments + def active_model_serializer; PostSerializer; end end class Comment < Model + def active_model_serializer; CommentSerializer; end end class UserSerializer < ActiveModel::Serializer @@ -428,38 +424,11 @@ class SerializerTest < ActiveModel::TestCase post.comments = [] array = [model, post, comments] - serializer = ActiveModel::Serializer::Finder.find(array, user).new(array, user) + serializer = array.active_model_serializer.new(array, user) assert_equal([ { :model => "Model" }, { :post => { :body => "Body of new post", :comments => [], :title => "New Post" } }, { :comment => { :title => "Comment1" } } ], serializer.as_json) end - - def test_array_serializer_respects_model_serializer - user = User.new(:first_name => "Jose", :last_name => "Valim") - user.model_serializer = User2Serializer - - array = [user] - serializer = ActiveModel::Serializer::Finder.find(array, user).new(array, {}) - assert_equal([ - { :user2 => { :last_name => "Valim", :first_name => "Jose", :ok => true } }, - ], serializer.as_json) - end - - def test_finder_respects_model_serializer - user = User.new(:first_name => "Jose", :last_name => "Valim") - assert_equal UserSerializer, user.model_serializer - - serializer = ActiveModel::Serializer::Finder.find(user, self).new(user, {}) - assert_equal({ - :user => { :last_name => "Valim", :first_name => "Jose"}, - }, serializer.as_json) - - user.model_serializer = User2Serializer - serializer = ActiveModel::Serializer::Finder.find(user, self).new(user, {}) - assert_equal({ - :user2 => { :last_name => "Valim", :first_name => "Jose", :ok => true }, - }, serializer.as_json) - end end \ No newline at end of file diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 2f1066016b..1372e71a61 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -542,6 +542,7 @@ module ActiveSupport #:nodoc: key = key.name if key.respond_to?(:name) @store[key] ||= Inflector.constantize(key) end + alias :[] :get def safe_get(key) key = key.name if key.respond_to?(:name) diff --git a/activesupport/test/class_cache_test.rb b/activesupport/test/class_cache_test.rb index 87f61dcfc8..b96f476ce6 100644 --- a/activesupport/test/class_cache_test.rb +++ b/activesupport/test/class_cache_test.rb @@ -49,6 +49,11 @@ module ActiveSupport end end + def test_get_alias + assert @cache.empty? + assert_equal @cache[ClassCacheTest.name], @cache.get(ClassCacheTest.name) + end + def test_safe_get_constantizes assert @cache.empty? assert_equal ClassCacheTest, @cache.safe_get(ClassCacheTest.name) -- cgit v1.2.3