Merge pull request #617 from konukhov/namespaced_serializers-0-9

Namespaced serializers #499
This commit is contained in:
Steve Klabnik
2014-08-31 20:00:47 -04:00
12 changed files with 163 additions and 35 deletions

View File

@@ -22,6 +22,7 @@ module ActiveModel
@resource_name = options[:resource_name]
@only = options[:only] ? Array(options[:only]) : nil
@except = options[:except] ? Array(options[:except]) : nil
@namespace = options[:namespace]
@key_format = options[:key_format] || options[:each_serializer].try(:key_format)
end
attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format
@@ -33,13 +34,13 @@ module ActiveModel
end
def serializer_for(item)
serializer_class = @each_serializer || Serializer.serializer_for(item) || DefaultSerializer
serializer_class = @each_serializer || Serializer.serializer_for(item, namespace: @namespace) || DefaultSerializer
serializer_class.new(item, scope: scope, key_format: key_format, only: @only, except: @except, polymorphic: @polymorphic)
end
def serializable_object
@object.map do |item|
serializer_for(item).serializable_object
serializer_for(item).serializable_object_with_notification
end
end
alias_method :serializable_array, :serializable_object
@@ -59,6 +60,7 @@ module ActiveModel
end
private
def instrumentation_keys
[:object, :scope, :root, :meta_key, :meta, :each_serializer, :resource_name, :key_format]
end

View File

@@ -1,5 +1,11 @@
require 'active_model/serializable/utils'
module ActiveModel
module Serializable
def self.included(base)
base.extend Utils
end
def as_json(options={})
instrument('!serialize') do
if root = options.fetch(:root, json_key)
@@ -12,6 +18,12 @@ module ActiveModel
end
end
def serializable_object_with_notification
instrument('!serialize') do
serializable_object
end
end
def serializable_data
embedded_in_root_associations.tap do |hash|
if respond_to?(:meta) && meta
@@ -20,11 +32,21 @@ module ActiveModel
end
end
def namespace
get_namespace && Utils._const_get(get_namespace)
end
def embedded_in_root_associations
{}
end
private
def get_namespace
modules = self.class.name.split('::')
modules[0..-2].join('::') if modules.size > 1
end
def instrument(action, &block)
payload = instrumentation_keys.inject({ serializer: self.class.name }) do |payload, key|
payload[:payload] = self.instance_variable_get(:"@#{key}")

View File

@@ -0,0 +1,12 @@
module ActiveModel
module Serializable
module Utils
extend self
def _const_get(const)
method = RUBY_VERSION >= '2.0' ? :const_get : :qualified_const_get
Object.send method, const
end
end
end
end

View File

@@ -55,32 +55,18 @@ end
end
attr_reader :key_format
if RUBY_VERSION >= '2.0'
def serializer_for(resource)
if resource.respond_to?(:to_ary)
if Object.constants.include?(:ArraySerializer)
::ArraySerializer
else
ArraySerializer
end
def serializer_for(resource, options = {})
if resource.respond_to?(:to_ary)
if Object.constants.include?(:ArraySerializer)
::ArraySerializer
else
begin
Object.const_get "#{resource.class.name}Serializer"
rescue NameError
nil
end
ArraySerializer
end
end
else
def serializer_for(resource)
if resource.respond_to?(:to_ary)
if Object.constants.include?(:ArraySerializer)
::ArraySerializer
else
ArraySerializer
end
else
"#{resource.class.name}Serializer".safe_constantize
else
begin
_const_get build_serializer_class(resource, options)
rescue NameError
nil
end
end
end
@@ -113,6 +99,14 @@ end
private
def build_serializer_class(resource, options)
"".tap do |klass_name|
klass_name << "#{options[:namespace]}::" if options[:namespace]
klass_name << options[:prefix].to_s.classify if options[:prefix]
klass_name << "#{resource.class.name}Serializer"
end
end
def associate(klass, *attrs)
options = attrs.extract_options!
@@ -219,7 +213,16 @@ end
def build_serializer(association)
object = send(association.name)
association.build_serializer(object, scope: scope)
association.build_serializer(object, association_options_for_serializer(association))
end
def association_options_for_serializer(association)
prefix = association.options[:prefix]
{ scope: scope }.tap do |opts|
opts[:namespace] = namespace if namespace
opts[:prefix] = prefix if prefix
end
end
def serialize(association)

View File

@@ -42,8 +42,8 @@ module ActiveModel
@embed_objects = embed == :object || embed == :objects
end
def serializer_from_object(object)
Serializer.serializer_for(object)
def serializer_from_object(object, options = {})
Serializer.serializer_for(object, options)
end
def default_serializer
@@ -51,7 +51,7 @@ module ActiveModel
end
def build_serializer(object, options = {})
serializer_class(object).new(object, options.merge(self.options))
serializer_class(object, options).new(object, options.merge(self.options))
end
end
end

View File

@@ -8,7 +8,7 @@ module ActiveModel
@key ||= "#{name.to_s.singularize}_ids"
end
def serializer_class(object)
def serializer_class(object, _)
if use_array_serializer?
ArraySerializer
else

View File

@@ -8,8 +8,8 @@ module ActiveModel
@key ||= "#{name}_id"
end
def serializer_class(object)
serializer_from_options || serializer_from_object(object) || default_serializer
def serializer_class(object, options = {})
serializer_from_options || serializer_from_object(object, options) || default_serializer
end
def build_serializer(object, options = {})