Skip to content

Commit

Permalink
allow multiple meta block and merge them if present
Browse files Browse the repository at this point in the history
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
    }
  }
}
```
  • Loading branch information
doits committed Jun 7, 2019
1 parent e0228da commit 05ca796
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
5 changes: 3 additions & 2 deletions lib/fast_jsonapi/object_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion lib/fast_jsonapi/serialization_core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,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 = {})
Expand Down
17 changes: 17 additions & 0 deletions spec/lib/object_serializer_class_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
31 changes: 31 additions & 0 deletions spec/lib/object_serializer_inheritance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit 05ca796

Please sign in to comment.