Skip to content

Commit 26d5fb7

Browse files
committed
Add support to polymorphic models
1 parent e8b9834 commit 26d5fb7

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

lib/active_model/array_serializer.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def initialize(object, options={})
1515
@object = object
1616
@scope = options[:scope]
1717
@root = options.fetch(:root, self.class._root)
18+
@polymorphic = options.fetch(:polymorphic, false)
1819
@meta_key = options[:meta_key] || :meta
1920
@meta = options[@meta_key]
2021
@each_serializer = options[:each_serializer]
@@ -33,7 +34,7 @@ def json_key
3334

3435
def serializer_for(item)
3536
serializer_class = @each_serializer || Serializer.serializer_for(item) || DefaultSerializer
36-
serializer_class.new(item, scope: scope, key_format: key_format, only: @only, except: @except)
37+
serializer_class.new(item, scope: scope, key_format: key_format, only: @only, except: @except, polymorphic: @polymorphic)
3738
end
3839

3940
def serializable_object

lib/active_model/serializer.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ def initialize(object, options={})
130130
@object = object
131131
@scope = options[:scope]
132132
@root = options.fetch(:root, self.class._root)
133+
@polymorphic = options.fetch(:polymorphic, false)
133134
@meta_key = options[:meta_key] || :meta
134135
@meta = options[@meta_key]
135136
@wrap_in_array = options[:_wrap_in_array]
@@ -138,7 +139,7 @@ def initialize(object, options={})
138139
@key_format = options[:key_format]
139140
@context = options[:context]
140141
end
141-
attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format, :context
142+
attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format, :context, :polymorphic
142143

143144
def json_key
144145
key = if root == true || root.nil?
@@ -225,9 +226,9 @@ def serialize(association)
225226
def serialize_ids(association)
226227
associated_data = send(association.name)
227228
if associated_data.respond_to?(:to_ary)
228-
associated_data.map { |elem| elem.read_attribute_for_serialization(association.embed_key) }
229+
associated_data.map { |elem| serialize_id(elem, association) }
229230
else
230-
associated_data.read_attribute_for_serialization(association.embed_key) if associated_data
231+
serialize_id(associated_data, association) if associated_data
231232
end
232233
end
233234

@@ -260,9 +261,19 @@ def serializable_object(options={})
260261
hash = attributes
261262
hash.merge! associations
262263
hash = convert_keys(hash) if key_format.present?
264+
hash = { :type => type_name(@object), type_name(@object) => hash } if @polymorphic
263265
@wrap_in_array ? [hash] : hash
264266
end
265267
alias_method :serializable_hash, :serializable_object
268+
269+
def serialize_id(elem, association)
270+
id = elem.read_attribute_for_serialization(association.embed_key)
271+
association.polymorphic? ? { id: id, type: type_name(elem) } : id
272+
end
273+
274+
def type_name(elem)
275+
elem.class.to_s.demodulize.underscore.to_sym
276+
end
266277
end
267278

268279
end

lib/active_model/serializer/association.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def initialize(name, options={})
1515
@name = name.to_s
1616
@options = options
1717
self.embed = options.fetch(:embed) { CONFIG.embed }
18+
@polymorphic = options.fetch(:polymorphic, false)
1819
@embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } }
1920
@key_format = options.fetch(:key_format) { CONFIG.key_format }
2021
@embed_key = options[:embed_key] || :id
@@ -27,13 +28,14 @@ def initialize(name, options={})
2728
@serializer_from_options = serializer.is_a?(String) ? serializer.constantize : serializer
2829
end
2930

30-
attr_reader :name, :embed_ids, :embed_objects
31+
attr_reader :name, :embed_ids, :embed_objects, :polymorphic
3132
attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, :root_key, :serializer_from_options, :options, :key_format, :embed_in_root_key, :embed_namespace
3233
alias embed_ids? embed_ids
3334
alias embed_objects? embed_objects
3435
alias embed_in_root? embed_in_root
3536
alias embed_in_root_key? embed_in_root_key
3637
alias embed_namespace? embed_namespace
38+
alias polymorphic? polymorphic
3739

3840
def embed=(embed)
3941
@embed_ids = embed == :id || embed == :ids

0 commit comments

Comments
 (0)