diff options
author | José Valim <jose.valim@gmail.com> | 2011-11-23 23:18:13 +0000 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2011-11-23 23:18:15 +0000 |
commit | 8896b4fdc8a543157cdf4dfc378607ebf6c10ab0 (patch) | |
tree | 5deca0d54d2c103d0a9e6167a756d638fc25e9ec /activemodel/lib/active_model/serializer.rb | |
parent | 0536ea8c7855222111fad6df71d0d09b77ea4317 (diff) | |
download | rails-8896b4fdc8a543157cdf4dfc378607ebf6c10ab0.tar.gz rails-8896b4fdc8a543157cdf4dfc378607ebf6c10ab0.tar.bz2 rails-8896b4fdc8a543157cdf4dfc378607ebf6c10ab0.zip |
Implement ArraySerializer and move old serialization API to a new namespace.
The following constants were renamed:
ActiveModel::Serialization => ActiveModel::Serializable
ActiveModel::Serializers::JSON => ActiveModel::Serializable::JSON
ActiveModel::Serializers::Xml => ActiveModel::Serializable::XML
The main motivation for such a change is that `ActiveModel::Serializers::JSON`
was not actually a serializer, but a module that when included allows the target to be serializable to JSON.
With such changes, we were able to clean up the namespace to add true serializers as the ArraySerializer.
Diffstat (limited to 'activemodel/lib/active_model/serializer.rb')
-rw-r--r-- | activemodel/lib/active_model/serializer.rb | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/activemodel/lib/active_model/serializer.rb b/activemodel/lib/active_model/serializer.rb index 6d0746a3e8..a541a1053d 100644 --- a/activemodel/lib/active_model/serializer.rb +++ b/activemodel/lib/active_model/serializer.rb @@ -1,10 +1,70 @@ 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 + # Active Model Array Serializer + class ArraySerializer + attr_reader :object, :scope + + def initialize(object, scope) + @object, @scope = object, scope + end + + def serializable_array + @object.map do |item| + if serializer = Serializer::Finder.find(item, scope) + serializer.new(item, scope) + else + item + end + end + end + + def as_json(*args) + serializable_array.as_json(*args) + end + end + + # 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 |