aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/serializer.rb
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2011-11-23 23:18:13 +0000
committerJosé Valim <jose.valim@gmail.com>2011-11-23 23:18:15 +0000
commit8896b4fdc8a543157cdf4dfc378607ebf6c10ab0 (patch)
tree5deca0d54d2c103d0a9e6167a756d638fc25e9ec /activemodel/lib/active_model/serializer.rb
parent0536ea8c7855222111fad6df71d0d09b77ea4317 (diff)
downloadrails-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.rb60
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