diff --git a/lib/fast_jsonapi/object_serializer.rb b/lib/fast_jsonapi/object_serializer.rb index c161fb6b..843b111d 100644 --- a/lib/fast_jsonapi/object_serializer.rb +++ b/lib/fast_jsonapi/object_serializer.rb @@ -123,7 +123,7 @@ def inherited(subclass) subclass.data_links = data_links.dup if data_links.present? subclass.cached = cached subclass.set_type(subclass.reflected_record_type) if subclass.reflected_record_type - subclass.meta_to_serialize = meta_to_serialize + subclass.meta_to_serialize = meta_to_serialize.dup if meta_to_serialize.present? end def reflected_record_type @@ -227,7 +227,8 @@ def belongs_to(relationship_name, options = {}, &block) end def meta(&block) - self.meta_to_serialize = block + self.meta_to_serialize ||= [] + self.meta_to_serialize.push(block) end def create_relationship(base_key, relationship_type, options, block) diff --git a/lib/fast_jsonapi/serialization_core.rb b/lib/fast_jsonapi/serialization_core.rb index 845aee75..2fdd1f8f 100644 --- a/lib/fast_jsonapi/serialization_core.rb +++ b/lib/fast_jsonapi/serialization_core.rb @@ -62,7 +62,13 @@ def relationships_hash(record, relationships = nil, fieldset = nil, params = {}) end def meta_hash(record, params = {}) - meta_to_serialize.call(record, params) + called = meta_to_serialize.map do |meta| + meta.call(record, params) + end.select(&:present?) + + return if called.blank? + + called.inject { |agg, meta| agg.deep_merge!(meta) } end def record_hash(record, fieldset, params = {}) diff --git a/spec/lib/object_serializer_class_methods_spec.rb b/spec/lib/object_serializer_class_methods_spec.rb index 6fe4718b..3f8d67aa 100644 --- a/spec/lib/object_serializer_class_methods_spec.rb +++ b/spec/lib/object_serializer_class_methods_spec.rb @@ -324,6 +324,23 @@ expect(serializable_hash[:data][:meta]).to eq ({ years_since_release: year_since_release_calculator(movie.release_year) }) end + context 'with a second meta call' do + before do + MovieSerializer.meta do + { + watch_count: 4426 + } + end + end + + it 'returns correct hash when serializable_hash is called' do + expect(serializable_hash[:data][:meta]).to eq ({ + years_since_release: year_since_release_calculator(movie.release_year), + watch_count: 4426 + }) + end + end + private def year_since_release_calculator(release_year) diff --git a/spec/lib/object_serializer_inheritance_spec.rb b/spec/lib/object_serializer_inheritance_spec.rb index beb74872..c37c143e 100644 --- a/spec/lib/object_serializer_inheritance_spec.rb +++ b/spec/lib/object_serializer_inheritance_spec.rb @@ -48,6 +48,12 @@ class UserSerializer has_many :addresses, cached: true belongs_to :country has_one :photo + + meta do |object| + { + user_meta: true + } + end end class Photo @@ -93,6 +99,12 @@ class EmployeeSerializer < UserSerializer attributes :compensation has_one :account + + meta do + { + employee_meta: true + } + end end it 'sets the correct record type' do @@ -165,4 +177,23 @@ class EmployeeSerializer < UserSerializer end end + + context 'when testing inheritance of meta' do + + it 'includes parent meta' do + subclass_meta = EmployeeSerializer.meta_to_serialize + superclass_meta = UserSerializer.meta_to_serialize + expect(subclass_meta).to include(*superclass_meta) + end + + it 'includes child meta' do + expect(EmployeeSerializer.meta_to_serialize.map(&:call)).to eq([{ user_meta: true }, { employee_meta: true }]) + end + + it 'doesnt change parent class attributes' do + EmployeeSerializer + expect(UserSerializer.meta_to_serialize.map(&:call)).to eq([{ user_meta: true }]) + end + end + end