File tree Expand file tree Collapse file tree 6 files changed +147
-0
lines changed Expand file tree Collapse file tree 6 files changed +147
-0
lines changed Original file line number Diff line number Diff line change 9
9
require 'active_model/serializer/fieldset'
10
10
require 'active_model/serializer/lint'
11
11
require 'active_model/serializer/links'
12
+ require 'active_model/serializer/meta'
12
13
require 'active_model/serializer/type'
13
14
14
15
# ActiveModel::Serializer is an abstract class that is
@@ -20,6 +21,7 @@ class Serializer
20
21
include Attributes
21
22
include Caching
22
23
include Links
24
+ include Meta
23
25
include Type
24
26
require 'active_model/serializer/adapter'
25
27
Original file line number Diff line number Diff line change @@ -8,6 +8,7 @@ class JsonApi < Base
8
8
autoload :Link
9
9
autoload :Association
10
10
autoload :ResourceIdentifier
11
+ autoload :Meta
11
12
autoload :Deserialization
12
13
13
14
# TODO: if we like this abstraction and other API objects to it,
@@ -150,6 +151,9 @@ def resource_object_for(serializer)
150
151
links = links_for ( serializer )
151
152
resource_object [ :links ] = links if links . any?
152
153
154
+ meta = meta_for ( serializer )
155
+ resource_object [ :meta ] = meta unless meta . nil?
156
+
153
157
resource_object
154
158
end
155
159
@@ -174,6 +178,10 @@ def links_for(serializer)
174
178
def pagination_links_for ( serializer , options )
175
179
JsonApi ::PaginationLinks . new ( serializer . object , options [ :serialization_context ] ) . serializable_hash ( options )
176
180
end
181
+
182
+ def meta_for ( serializer )
183
+ Meta . new ( serializer ) . as_json
184
+ end
177
185
end
178
186
end
179
187
end
Original file line number Diff line number Diff line change
1
+ module ActiveModel
2
+ class Serializer
3
+ module Adapter
4
+ class JsonApi
5
+ class Meta
6
+ def initialize ( serializer )
7
+ @object = serializer . object
8
+ @scope = serializer . scope
9
+
10
+ # Use the return value of the block unless it is nil.
11
+ if serializer . _meta . respond_to? ( :call )
12
+ @value = instance_eval ( &serializer . _meta )
13
+ else
14
+ @value = serializer . _meta
15
+ end
16
+ end
17
+
18
+ def as_json
19
+ @value
20
+ end
21
+
22
+ protected
23
+
24
+ attr_reader :object , :scope
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
Original file line number Diff line number Diff line change
1
+ module ActiveModel
2
+ class Serializer
3
+ module Meta
4
+ extend ActiveSupport ::Concern
5
+
6
+ included do
7
+ with_options instance_writer : false , instance_reader : true do |serializer |
8
+ serializer . class_attribute :_meta # @api private
9
+ end
10
+
11
+ extend ActiveSupport ::Autoload
12
+ end
13
+
14
+ module ClassMethods
15
+ # Set the JSON API meta attribute of a serializer.
16
+ # @example
17
+ # class AdminAuthorSerializer < ActiveModel::Serializer
18
+ # meta { stuff: 'value' }
19
+ # @example
20
+ # meta do
21
+ # { comment_count: object.comments.count }
22
+ # end
23
+ def meta ( value = nil , &block )
24
+ self . _meta = block || value
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
Original file line number Diff line number Diff line change
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ module Adapter
6
+ class JsonApi
7
+ class ResourceMetaTest < Minitest ::Test
8
+ class MetaHashPostSerializer < ActiveModel ::Serializer
9
+ attributes :id
10
+ meta stuff : 'value'
11
+ end
12
+
13
+ class MetaBlockPostSerializer < ActiveModel ::Serializer
14
+ attributes :id
15
+ meta do
16
+ { comments_count : object . comments . count }
17
+ end
18
+ end
19
+
20
+ def setup
21
+ @post = Post . new ( id : 1337 , comments : [ ] , author : nil )
22
+ end
23
+
24
+ def test_meta_hash_object_resource
25
+ hash = ActiveModel ::SerializableResource . new (
26
+ @post ,
27
+ serializer : MetaHashPostSerializer ,
28
+ adapter : :json_api
29
+ ) . serializable_hash
30
+ expected = {
31
+ stuff : 'value'
32
+ }
33
+ assert_equal ( expected , hash [ :data ] [ :meta ] )
34
+ end
35
+
36
+ def test_meta_block_object_resource
37
+ hash = ActiveModel ::SerializableResource . new (
38
+ @post ,
39
+ serializer : MetaBlockPostSerializer ,
40
+ adapter : :json_api
41
+ ) . serializable_hash
42
+ expected = {
43
+ comments_count : @post . comments . count
44
+ }
45
+ assert_equal ( expected , hash [ :data ] [ :meta ] )
46
+ end
47
+
48
+ def test_meta_object_resource_in_array
49
+ hash = ActiveModel ::SerializableResource . new (
50
+ [ @post , @post ] ,
51
+ each_serializer : MetaBlockPostSerializer ,
52
+ adapter : :json_api
53
+ ) . serializable_hash
54
+ expected = {
55
+ comments_count : @post . comments . count
56
+ }
57
+ assert_equal ( [ expected , expected ] , hash [ :data ] . map { |obj | obj [ :meta ] } )
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
Original file line number Diff line number Diff line change 3
3
module ActiveModel
4
4
class Serializer
5
5
class MetaTest < ActiveSupport ::TestCase
6
+ MetaBlogSerializer = Class . new ( ActiveModel ::Serializer )
7
+
6
8
def setup
7
9
@blog = Blog . new ( id : 1 ,
8
10
name : 'AMS Hints' ,
@@ -125,6 +127,20 @@ def test_meta_is_present_on_arrays_with_root
125
127
}
126
128
assert_equal ( expected , actual )
127
129
end
130
+
131
+ def test_meta_is_set_with_direct_attributes
132
+ MetaBlogSerializer . meta stuff : 'value'
133
+ blog_meta_serializer = MetaBlogSerializer . new ( @blog )
134
+ assert_equal ( blog_meta_serializer . meta , stuff : 'value' )
135
+ end
136
+
137
+ def test_meta_is_set_with_block
138
+ MetaBlogSerializer . meta do
139
+ { articles_count : object . articles . count }
140
+ end
141
+ blog_meta_serializer = MetaBlogSerializer . new ( @blog )
142
+ assert_equal ( blog_meta_serializer . meta , articles_count : @blog . articles . count )
143
+ end
128
144
end
129
145
end
130
146
end
You can’t perform that action at this time.
0 commit comments