Skip to content

Commit 54725ac

Browse files
committed
Add support for inline serializers.
1 parent 9da2061 commit 54725ac

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

lib/active_model/serializer/associations.rb

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,53 +34,92 @@ def inherited(base)
3434

3535
# @param [Symbol] name of the association
3636
# @param [Hash<Symbol => any>] options for the reflection
37+
# @param [Block] optional inline definition of the serializer for this association
3738
# @return [void]
3839
#
3940
# @example
4041
# has_many :comments, serializer: CommentSummarySerializer
42+
# has_many :comments do
43+
# attributes :id, :content
44+
# end
4145
#
42-
def has_many(name, options = {})
43-
associate HasManyReflection.new(name, options)
46+
def has_many(name, options = {}, &block)
47+
associate(HasManyReflection.new(name, options), &block)
4448
end
4549

4650
# @param [Symbol] name of the association
4751
# @param [Hash<Symbol => any>] options for the reflection
52+
# @param [Block] optional inline definition of the serializer for this association
4853
# @return [void]
4954
#
5055
# @example
5156
# belongs_to :author, serializer: AuthorSerializer
57+
# belongs_to :author do
58+
# attributes :id, :name
59+
# end
5260
#
53-
def belongs_to(name, options = {})
54-
associate BelongsToReflection.new(name, options)
61+
def belongs_to(name, options = {}, &block)
62+
associate(BelongsToReflection.new(name, options), &block)
5563
end
5664

5765
# @param [Symbol] name of the association
5866
# @param [Hash<Symbol => any>] options for the reflection
67+
# @param [Block] optional inline definition of the serializer for this association
5968
# @return [void]
6069
#
6170
# @example
6271
# has_one :author, serializer: AuthorSerializer
72+
# has_one :author do
73+
# attributes :id, :name
74+
# end
6375
#
64-
def has_one(name, options = {})
65-
associate HasOneReflection.new(name, options)
76+
def has_one(name, options = {}, &block)
77+
associate(HasOneReflection.new(name, options), &block)
6678
end
6779

6880
private
6981

70-
# Add reflection and define {name} accessor.
82+
# Add reflection and define {name} accessor and nested serializer.
7183
# @param [ActiveModel::Serializer::Reflection] reflection
84+
# @param [Block] optional inline definition of the serializer for this association
7285
# @return [void]
7386
#
7487
# @api private
7588
#
76-
def associate(reflection)
89+
def associate(reflection, &block)
7790
self._reflections = _reflections.dup
7891

7992
define_method reflection.name do
8093
object.send reflection.name
8194
end unless method_defined?(reflection.name)
8295

83-
self._reflections << reflection
96+
_reflections << reflection
97+
98+
define_nested_serializer(reflection.name.to_s.singularize, &block) if block_given?
99+
end
100+
101+
# Define a nested serializer
102+
# @param [String] resource_name The name of the association
103+
# @param [Block] inline definition of the serializer for this association
104+
# @return [void]
105+
#
106+
# @example
107+
# Namespace::PostSerializer.define_nested_serializer("comment") do
108+
# attributes :id, :content
109+
# end
110+
#
111+
# is equivalent to
112+
# class Namespace::PostSerializer::CommentSerializer < ActiveModel::Serializer
113+
# attributes :id, :content
114+
# end
115+
#
116+
# @api private
117+
#
118+
def define_nested_serializer(resource_name, &block)
119+
serializer_name = "#{resource_name.camelize}Serializer"
120+
serializer = Class.new(ActiveModel::Serializer)
121+
serializer.class_eval(&block)
122+
const_set(serializer_name, serializer)
84123
end
85124
end
86125

0 commit comments

Comments
 (0)