@@ -9,8 +9,9 @@ def self.serialize(resource, **options)
99
1010 attr_reader :context
1111
12- def initialize ( context :)
12+ def initialize ( context :, include : nil )
1313 @context = context
14+ @include = normalize_include_options ( include )
1415 end
1516
1617 def serialize ( resource )
@@ -28,7 +29,7 @@ def serialize?(resource)
2829 private
2930
3031 def serialize_resource ( resource )
31- return resource . identifier if serialized_resources . include ?( resource )
32+ return serialize_identifier ( resource ) if serialized ?( resource )
3233
3334 serialized_resources << resource
3435
@@ -37,34 +38,48 @@ def serialize_resource(resource)
3738 serialized = { }
3839
3940 resource . attribute_names . each do |name |
40- serialized [ name ] = resource . send ( name )
41+ serialized [ name ] = serialize_attribute ( resource , name )
4142 end
4243
4344 resource . association_names . each do |name |
44- next unless result = serialize_association ( resource . send ( name ) )
45+ next unless result = serialize_association ( resource , name )
4546
4647 serialized [ name ] = result
4748 end
4849
4950 serialized
5051 end
5152
52- def serialize_association ( association )
53- return unless association
53+ def serialize_attribute ( resource , name )
54+ resource . send ( name )
55+ end
56+
57+ def serialize_association ( resource , name )
58+ return unless association = resource . send ( name )
59+ return serialize_identifier ( association ) unless include? ( name )
60+
61+ with_include_for ( name ) do
62+ case association
63+ when Userlist ::Push ::ResourceCollection
64+ serialize_collection ( association )
65+ when Userlist ::Push ::Resource
66+ serialize_resource ( association )
67+ else
68+ raise "Cannot serialize association type: #{ association . class } "
69+ end
70+ end
71+ end
5472
55- case association
56- when Userlist ::Push ::ResourceCollection
57- serialize_collection ( association )
73+ def serialize_identifier ( resource )
74+ case resource
5875 when Userlist ::Push ::Resource
59- serialize_resource ( association )
60- else
61- raise "Cannot serialize association type: #{ association . class } "
76+ resource . identifier
6277 end
6378 end
6479
6580 def serialize_collection ( collection )
6681 serialized = collection
67- . map ( &method ( :serialize_association ) )
82+ . map ( &method ( :serialize_resource ) )
6883 . compact
6984 . reject ( &:empty? )
7085
@@ -74,6 +89,36 @@ def serialize_collection(collection)
7489 def serialized_resources
7590 @serialized_resources ||= Set . new
7691 end
92+
93+ def serialized? ( resource )
94+ serialized_resources . include? ( resource )
95+ end
96+
97+ def include? ( name )
98+ @include . nil? || @include . fetch ( name . to_sym , false )
99+ end
100+
101+ def with_include_for ( name )
102+ original_include = @include
103+ @include = @include &.fetch ( name . to_sym , false )
104+
105+ yield
106+ ensure
107+ @include = original_include
108+ end
109+
110+ def normalize_include_options ( value )
111+ case value
112+ when Array
113+ value . inject ( { } ) { |acc , v | acc . merge ( normalize_include_options ( v ) ) }
114+ when Hash
115+ value . to_h { |k , v | [ k . to_sym , normalize_include_options ( v ) ] }
116+ when Symbol , String
117+ { value . to_sym => { } }
118+ when false
119+ { }
120+ end
121+ end
77122 end
78123 end
79124end
0 commit comments