Skip to content

Commit a9b8aee

Browse files
committed
allow multiple meta block and merge them if present
Useful for includes and inheritance: ```rb module SomeModule extend ActiveSupport::Concern included do meta do { module_meta: true } end end end class UserSerializer include FastJsonapi::ObjectSerializer include SomeModule meta do { user_meta: true } end end class EmployeeSerializer < UserSerializer meta do { employee_meta: true } end end EmployeeSerializer.new(employee).serializable_hash { data: { [...] meta: { module_meta: true, user_meta: true, employee_meta: true } } } ```
1 parent 83e7fb6 commit a9b8aee

File tree

4 files changed

+58
-3
lines changed

4 files changed

+58
-3
lines changed

lib/fast_jsonapi/object_serializer.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def inherited(subclass)
123123
subclass.data_links = data_links.dup if data_links.present?
124124
subclass.cached = cached
125125
subclass.set_type(subclass.reflected_record_type) if subclass.reflected_record_type
126-
subclass.meta_to_serialize = meta_to_serialize
126+
subclass.meta_to_serialize = meta_to_serialize.dup if meta_to_serialize.present?
127127
end
128128

129129
def reflected_record_type
@@ -227,7 +227,8 @@ def belongs_to(relationship_name, options = {}, &block)
227227
end
228228

229229
def meta(&block)
230-
self.meta_to_serialize = block
230+
self.meta_to_serialize ||= []
231+
self.meta_to_serialize.push(block)
231232
end
232233

233234
def create_relationship(base_key, relationship_type, options, block)

lib/fast_jsonapi/serialization_core.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,13 @@ def relationships_hash(record, relationships = nil, fieldset = nil, params = {})
6262
end
6363

6464
def meta_hash(record, params = {})
65-
meta_to_serialize.call(record, params)
65+
called = meta_to_serialize.map do |meta|
66+
meta.call(record, params)
67+
end.select(&:present?)
68+
69+
return if called.blank?
70+
71+
called.inject { |agg, meta| agg.deep_merge!(meta) }
6672
end
6773

6874
def record_hash(record, fieldset, params = {})

spec/lib/object_serializer_class_methods_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,23 @@
324324
expect(serializable_hash[:data][:meta]).to eq ({ years_since_release: year_since_release_calculator(movie.release_year) })
325325
end
326326

327+
context 'with a second meta call' do
328+
before do
329+
MovieSerializer.meta do
330+
{
331+
watch_count: 4426
332+
}
333+
end
334+
end
335+
336+
it 'returns correct hash when serializable_hash is called' do
337+
expect(serializable_hash[:data][:meta]).to eq ({
338+
years_since_release: year_since_release_calculator(movie.release_year),
339+
watch_count: 4426
340+
})
341+
end
342+
end
343+
327344
private
328345

329346
def year_since_release_calculator(release_year)

spec/lib/object_serializer_inheritance_spec.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ class UserSerializer
4848
has_many :addresses, cached: true
4949
belongs_to :country
5050
has_one :photo
51+
52+
meta do |object|
53+
{
54+
user_meta: true
55+
}
56+
end
5157
end
5258

5359
class Photo
@@ -93,6 +99,12 @@ class EmployeeSerializer < UserSerializer
9399
attributes :compensation
94100

95101
has_one :account
102+
103+
meta do
104+
{
105+
employee_meta: true
106+
}
107+
end
96108
end
97109

98110
it 'sets the correct record type' do
@@ -165,4 +177,23 @@ class EmployeeSerializer < UserSerializer
165177
end
166178

167179
end
180+
181+
context 'when testing inheritance of meta' do
182+
183+
it 'includes parent meta' do
184+
subclass_meta = EmployeeSerializer.meta_to_serialize
185+
superclass_meta = UserSerializer.meta_to_serialize
186+
expect(subclass_meta).to include(*superclass_meta)
187+
end
188+
189+
it 'includes child meta' do
190+
expect(EmployeeSerializer.meta_to_serialize.map(&:call)).to eq([{ user_meta: true }, { employee_meta: true }])
191+
end
192+
193+
it 'doesnt change parent class attributes' do
194+
EmployeeSerializer
195+
expect(UserSerializer.meta_to_serialize.map(&:call)).to eq([{ user_meta: true }])
196+
end
197+
end
198+
168199
end

0 commit comments

Comments
 (0)