commit
						92bcab0a3f
					
				
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							@ -245,6 +245,23 @@ class MovieSerializer
 | 
			
		||||
end
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Meta Per Resource
 | 
			
		||||
 | 
			
		||||
For every resource in the collection, you can include a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```ruby
 | 
			
		||||
class MovieSerializer
 | 
			
		||||
  include FastJsonapi::ObjectSerializer
 | 
			
		||||
 | 
			
		||||
  meta do |movie|
 | 
			
		||||
    {
 | 
			
		||||
      years_since_release: Date.current.year - movie.year
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Compound Document
 | 
			
		||||
 | 
			
		||||
Support for top-level and nested included associations through ` options[:include] `.
 | 
			
		||||
@ -351,15 +368,15 @@ class MovieSerializer
 | 
			
		||||
  include FastJsonapi::ObjectSerializer
 | 
			
		||||
 | 
			
		||||
  attributes :name, :year
 | 
			
		||||
  attribute :release_year, if: Proc.new do |record|
 | 
			
		||||
  attribute :release_year, if: Proc.new { |record|
 | 
			
		||||
    # Release year will only be serialized if it's greater than 1990
 | 
			
		||||
    record.release_year > 1990
 | 
			
		||||
  end
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  attribute :director, if: Proc.new do |record, params|
 | 
			
		||||
  attribute :director, if: Proc.new { |record, params|
 | 
			
		||||
    # The director will be serialized only if the :admin key of params is true
 | 
			
		||||
    params && params[:admin] == true
 | 
			
		||||
  end
 | 
			
		||||
  }
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# ...
 | 
			
		||||
@ -409,6 +426,7 @@ serializer.serializable_hash
 | 
			
		||||
Option | Purpose | Example
 | 
			
		||||
------------ | ------------- | -------------
 | 
			
		||||
set_type | Type name of Object | ```set_type :movie ```
 | 
			
		||||
key | Key of Object | ```belongs_to :owner, key: :user ```
 | 
			
		||||
set_id | ID of Object | ```set_id :owner_id ```
 | 
			
		||||
cache_options | Hash to enable caching and set cache length | ```cache_options enabled: true, cache_length: 12.hours, race_condition_ttl: 10.seconds```
 | 
			
		||||
id_method_name | Set custom method name to get ID of an object | ```has_many :locations, id_method_name: :place_ids ```
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
require 'active_support/core_ext/object'
 | 
			
		||||
require 'active_support/json'
 | 
			
		||||
require 'active_support/concern'
 | 
			
		||||
require 'active_support/inflector'
 | 
			
		||||
require 'fast_jsonapi/attribute'
 | 
			
		||||
@ -65,7 +65,7 @@ module FastJsonapi
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def serialized_json
 | 
			
		||||
      self.class.to_json(serializable_hash)
 | 
			
		||||
      ActiveSupport::JSON.encode(serializable_hash)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
@ -120,6 +120,7 @@ module FastJsonapi
 | 
			
		||||
        subclass.data_links = data_links
 | 
			
		||||
        subclass.cached = cached
 | 
			
		||||
        subclass.set_type(subclass.reflected_record_type) if subclass.reflected_record_type
 | 
			
		||||
        subclass.meta_to_serialize = meta_to_serialize
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def reflected_record_type
 | 
			
		||||
@ -218,6 +219,10 @@ module FastJsonapi
 | 
			
		||||
        add_relationship(relationship)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def meta(&block)
 | 
			
		||||
        self.meta_to_serialize = block
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def create_relationship(base_key, relationship_type, options, block)
 | 
			
		||||
        name = base_key.to_sym
 | 
			
		||||
        if relationship_type == :has_many
 | 
			
		||||
@ -232,7 +237,11 @@ module FastJsonapi
 | 
			
		||||
        Relationship.new(
 | 
			
		||||
          key: options[:key] || run_key_transform(base_key),
 | 
			
		||||
          name: name,
 | 
			
		||||
          id_method_name: options[:id_method_name] || "#{base_serialization_key}#{id_postfix}".to_sym,
 | 
			
		||||
          id_method_name: compute_id_method_name(
 | 
			
		||||
            options[:id_method_name],
 | 
			
		||||
            "#{base_serialization_key}#{id_postfix}".to_sym,
 | 
			
		||||
            block
 | 
			
		||||
          ),
 | 
			
		||||
          record_type: options[:record_type] || run_key_transform(base_key_sym),
 | 
			
		||||
          object_method_name: options[:object_method_name] || name,
 | 
			
		||||
          object_block: block,
 | 
			
		||||
@ -240,10 +249,19 @@ module FastJsonapi
 | 
			
		||||
          relationship_type: relationship_type,
 | 
			
		||||
          cached: options[:cached],
 | 
			
		||||
          polymorphic: fetch_polymorphic_option(options),
 | 
			
		||||
          conditional_proc: options[:if]
 | 
			
		||||
          conditional_proc: options[:if],
 | 
			
		||||
          transform_method: @transform_method
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def compute_id_method_name(custom_id_method_name, id_method_name_from_relationship, block)
 | 
			
		||||
        if block.present?
 | 
			
		||||
          custom_id_method_name || :id
 | 
			
		||||
        else
 | 
			
		||||
          custom_id_method_name || id_method_name_from_relationship
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def compute_serializer_name(serializer_key)
 | 
			
		||||
        return serializer_key unless serializer_key.is_a? Symbol
 | 
			
		||||
        namespace = self.name.gsub(/()?\w+Serializer$/, '')
 | 
			
		||||
@ -275,10 +293,10 @@ module FastJsonapi
 | 
			
		||||
        includes.detect do |include_item|
 | 
			
		||||
          klass = self
 | 
			
		||||
          parse_include_item(include_item).each do |parsed_include|
 | 
			
		||||
            relationship_to_include = klass.relationships_to_serialize[parsed_include]
 | 
			
		||||
            relationships_to_serialize = klass.relationships_to_serialize || {}
 | 
			
		||||
            relationship_to_include = relationships_to_serialize[parsed_include]
 | 
			
		||||
            raise ArgumentError, "#{parsed_include} is not specified as a relationship on #{klass.name}" unless relationship_to_include
 | 
			
		||||
            raise NotImplementedError if relationship_to_include.polymorphic.is_a?(Hash)
 | 
			
		||||
            klass = relationship_to_include.serializer.to_s.constantize
 | 
			
		||||
            klass = relationship_to_include.serializer.to_s.constantize unless relationship_to_include.polymorphic.is_a?(Hash)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
module FastJsonapi
 | 
			
		||||
  class Relationship
 | 
			
		||||
    attr_reader :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc
 | 
			
		||||
    attr_reader :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method
 | 
			
		||||
 | 
			
		||||
    def initialize(
 | 
			
		||||
      key:,
 | 
			
		||||
@ -13,7 +13,8 @@ module FastJsonapi
 | 
			
		||||
      relationship_type:,
 | 
			
		||||
      cached: false,
 | 
			
		||||
      polymorphic:,
 | 
			
		||||
      conditional_proc:
 | 
			
		||||
      conditional_proc:,
 | 
			
		||||
      transform_method:
 | 
			
		||||
    )
 | 
			
		||||
      @key = key
 | 
			
		||||
      @name = name
 | 
			
		||||
@ -26,6 +27,7 @@ module FastJsonapi
 | 
			
		||||
      @cached = cached
 | 
			
		||||
      @polymorphic = polymorphic
 | 
			
		||||
      @conditional_proc = conditional_proc
 | 
			
		||||
      @transform_method = transform_method
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def serialize(record, serialization_params, output_hash)
 | 
			
		||||
@ -68,7 +70,7 @@ module FastJsonapi
 | 
			
		||||
 | 
			
		||||
    def id_hash_from_record(record, record_types)
 | 
			
		||||
      # memoize the record type within the record_types dictionary, then assigning to record_type:
 | 
			
		||||
      associated_record_type = record_types[record.class] ||= record.class.name.underscore.to_sym
 | 
			
		||||
      associated_record_type = record_types[record.class] ||= run_key_transform(record.class.name.demodulize.underscore)
 | 
			
		||||
      id_hash(record.id, associated_record_type)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -86,14 +88,20 @@ module FastJsonapi
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def fetch_id(record, params)
 | 
			
		||||
      unless object_block.nil?
 | 
			
		||||
      if object_block.present?
 | 
			
		||||
        object = object_block.call(record, params)
 | 
			
		||||
 | 
			
		||||
        return object.map(&:id) if object.respond_to? :map
 | 
			
		||||
        return object.try(:id)
 | 
			
		||||
        return object.map { |item| item.public_send(id_method_name) } if object.respond_to? :map
 | 
			
		||||
        return object.try(id_method_name)
 | 
			
		||||
      end
 | 
			
		||||
      record.public_send(id_method_name)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
      record.public_send(id_method_name)
 | 
			
		||||
    def run_key_transform(input)
 | 
			
		||||
      if self.transform_method.present?
 | 
			
		||||
        input.to_s.send(*self.transform_method).to_sym
 | 
			
		||||
      else
 | 
			
		||||
        input.to_sym
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -21,7 +21,8 @@ module FastJsonapi
 | 
			
		||||
                      :cache_length,
 | 
			
		||||
                      :race_condition_ttl,
 | 
			
		||||
                      :cached,
 | 
			
		||||
                      :data_links
 | 
			
		||||
                      :data_links,
 | 
			
		||||
                      :meta_to_serialize
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -57,6 +58,10 @@ module FastJsonapi
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def meta_hash(record, params = {})
 | 
			
		||||
        meta_to_serialize.call(record, params)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def record_hash(record, fieldset, params = {})
 | 
			
		||||
        if cached
 | 
			
		||||
          record_hash = Rails.cache.fetch(record.cache_key, expires_in: cache_length, race_condition_ttl: race_condition_ttl) do
 | 
			
		||||
@ -67,13 +72,15 @@ module FastJsonapi
 | 
			
		||||
            temp_hash[:links] = links_hash(record, params) if data_links.present?
 | 
			
		||||
            temp_hash
 | 
			
		||||
          end
 | 
			
		||||
          record_hash[:relationships] = record_hash[:relationships].merge(relationships_hash(record, uncachable_relationships_to_serialize, params)) if uncachable_relationships_to_serialize.present?
 | 
			
		||||
          record_hash[:relationships] = record_hash[:relationships].merge(relationships_hash(record, uncachable_relationships_to_serialize, fieldset, params)) if uncachable_relationships_to_serialize.present?
 | 
			
		||||
          record_hash[:meta] = meta_hash(record, params) if meta_to_serialize.present?
 | 
			
		||||
          record_hash
 | 
			
		||||
        else
 | 
			
		||||
          record_hash = id_hash(id_from_record(record), record_type, true)
 | 
			
		||||
          record_hash[:attributes] = attributes_hash(record, fieldset, params) if attributes_to_serialize.present?
 | 
			
		||||
          record_hash[:relationships] = relationships_hash(record, nil, fieldset, params) if relationships_to_serialize.present?
 | 
			
		||||
          record_hash[:links] = links_hash(record, params) if data_links.present?
 | 
			
		||||
          record_hash[:meta] = meta_hash(record, params) if meta_to_serialize.present?
 | 
			
		||||
          record_hash
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
@ -112,9 +119,10 @@ module FastJsonapi
 | 
			
		||||
            next unless relationships_to_serialize && relationships_to_serialize[item]
 | 
			
		||||
            relationship_item = relationships_to_serialize[item]
 | 
			
		||||
            next unless relationship_item.include_relationship?(record, params)
 | 
			
		||||
            raise NotImplementedError if relationship_item.polymorphic.is_a?(Hash)
 | 
			
		||||
            unless relationship_item.polymorphic.is_a?(Hash)
 | 
			
		||||
              record_type = relationship_item.record_type
 | 
			
		||||
              serializer = relationship_item.serializer.to_s.constantize
 | 
			
		||||
            end
 | 
			
		||||
            relationship_type = relationship_item.relationship_type
 | 
			
		||||
 | 
			
		||||
            included_objects = relationship_item.fetch_associated_object(record, params)
 | 
			
		||||
@ -122,12 +130,17 @@ module FastJsonapi
 | 
			
		||||
            included_objects = [included_objects] unless relationship_type == :has_many
 | 
			
		||||
 | 
			
		||||
            included_objects.each do |inc_obj|
 | 
			
		||||
              if relationship_item.polymorphic.is_a?(Hash)
 | 
			
		||||
                record_type = inc_obj.class.name.demodulize.underscore
 | 
			
		||||
                serializer = self.compute_serializer_name(inc_obj.class.name.demodulize.to_sym).to_s.constantize
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
              if remaining_items(items)
 | 
			
		||||
                serializer_records = serializer.get_included_records(inc_obj, remaining_items(items), known_included_objects, fieldsets)
 | 
			
		||||
                serializer_records = serializer.get_included_records(inc_obj, remaining_items(items), known_included_objects, fieldsets, params)
 | 
			
		||||
                included_records.concat(serializer_records) unless serializer_records.empty?
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
              code = "#{record_type}_#{inc_obj.id}"
 | 
			
		||||
              code = "#{record_type}_#{serializer.id_from_record(inc_obj)}"
 | 
			
		||||
              next if known_included_objects.key?(code)
 | 
			
		||||
 | 
			
		||||
              known_included_objects[code] = inc_obj
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,3 @@
 | 
			
		||||
module FastJsonapi
 | 
			
		||||
  VERSION = "1.3"
 | 
			
		||||
  VERSION = "1.4"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -87,6 +87,31 @@ describe FastJsonapi::ObjectSerializer do
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#has_many with block and id_method_name' do
 | 
			
		||||
    before do
 | 
			
		||||
      MovieSerializer.has_many(:awards, id_method_name: :imdb_award_id) do |movie|
 | 
			
		||||
        movie.actors.map(&:awards).flatten
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    after do
 | 
			
		||||
      MovieSerializer.relationships_to_serialize.delete(:awards)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'awards is not included' do
 | 
			
		||||
      subject(:hash) { MovieSerializer.new(movie).serializable_hash }
 | 
			
		||||
 | 
			
		||||
      it 'returns correct hash where id is obtained from the method specified via `id_method_name`' do
 | 
			
		||||
        expected_award_data = movie.actors.map(&:awards).flatten.map do |actor|
 | 
			
		||||
          { id: actor.imdb_award_id.to_s, type: actor.class.name.downcase.to_sym }
 | 
			
		||||
        end
 | 
			
		||||
        serialized_award_data = hash[:data][:relationships][:awards][:data]
 | 
			
		||||
 | 
			
		||||
        expect(serialized_award_data).to eq(expected_award_data)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#belongs_to' do
 | 
			
		||||
    subject(:relationship) { MovieSerializer.relationships_to_serialize[:area] }
 | 
			
		||||
 | 
			
		||||
@ -249,6 +274,34 @@ describe FastJsonapi::ObjectSerializer do
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#meta' do
 | 
			
		||||
    subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash }
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      movie.release_year = 2008
 | 
			
		||||
      MovieSerializer.meta do |movie|
 | 
			
		||||
        {
 | 
			
		||||
          years_since_release: year_since_release_calculator(movie.release_year)
 | 
			
		||||
        }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    after do
 | 
			
		||||
      movie.release_year = nil
 | 
			
		||||
      MovieSerializer.meta_to_serialize = nil
 | 
			
		||||
    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) })
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
    def year_since_release_calculator(release_year)
 | 
			
		||||
      Date.current.year - release_year
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#link' do
 | 
			
		||||
    subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										51
									
								
								spec/lib/object_serializer_polymorphic_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								spec/lib/object_serializer_polymorphic_spec.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
require 'spec_helper'
 | 
			
		||||
 | 
			
		||||
describe FastJsonapi::ObjectSerializer do
 | 
			
		||||
  class List
 | 
			
		||||
    attr_accessor :id, :name, :items
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class ChecklistItem
 | 
			
		||||
    attr_accessor :id, :name
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class Car
 | 
			
		||||
    attr_accessor :id, :model, :year
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class ListSerializer
 | 
			
		||||
    include FastJsonapi::ObjectSerializer
 | 
			
		||||
    set_type :list
 | 
			
		||||
    attributes :name
 | 
			
		||||
    set_key_transform :dash
 | 
			
		||||
    has_many :items, polymorphic: true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  let(:car) do
 | 
			
		||||
    car = Car.new
 | 
			
		||||
    car.id = 1
 | 
			
		||||
    car.model = 'Toyota Corolla'
 | 
			
		||||
    car.year = 1987
 | 
			
		||||
    car
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  let(:checklist_item) do
 | 
			
		||||
    checklist_item = ChecklistItem.new
 | 
			
		||||
    checklist_item.id = 2
 | 
			
		||||
    checklist_item.name = 'Do this action!'
 | 
			
		||||
    checklist_item
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context 'when serializing id and type of polymorphic relationships' do
 | 
			
		||||
    it 'should return correct type when transform_method is specified' do
 | 
			
		||||
      list = List.new
 | 
			
		||||
      list.id = 1
 | 
			
		||||
      list.items = [checklist_item, car]
 | 
			
		||||
      list_hash = ListSerializer.new(list).to_hash
 | 
			
		||||
      record_type = list_hash[:data][:relationships][:items][:data][0][:type]
 | 
			
		||||
      expect(record_type).to eq 'checklist-item'.to_sym
 | 
			
		||||
      record_type = list_hash[:data][:relationships][:items][:data][1][:type]
 | 
			
		||||
      expect(record_type).to eq 'car'.to_sym
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -158,6 +158,32 @@ describe FastJsonapi::ObjectSerializer do
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context 'id attribute is the same for actors and not a primary key' do
 | 
			
		||||
    before do
 | 
			
		||||
      ActorSerializer.set_id :email
 | 
			
		||||
      movie.actor_ids = [0, 0, 0]
 | 
			
		||||
      class << movie
 | 
			
		||||
        def actors
 | 
			
		||||
          super.each_with_index { |actor, i| actor.email = "actor#{i}@email.com" }
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    after { ActorSerializer.set_id nil }
 | 
			
		||||
 | 
			
		||||
    let(:options) { { include: ['actors'] } }
 | 
			
		||||
    subject { MovieSerializer.new(movie, options).serializable_hash }
 | 
			
		||||
 | 
			
		||||
    it 'returns all actors in includes' do
 | 
			
		||||
 | 
			
		||||
      expect(
 | 
			
		||||
        subject[:included].select { |i| i[:type] == :actor }.map { |i| i[:id] }
 | 
			
		||||
      ).to eq(
 | 
			
		||||
        movie.actors.map(&:email)
 | 
			
		||||
      )
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context 'nested includes' do
 | 
			
		||||
    it 'has_many to belongs_to: returns correct nested includes when serializable_hash is called' do
 | 
			
		||||
      # 3 actors, 3 agencies
 | 
			
		||||
@ -252,10 +278,24 @@ describe FastJsonapi::ObjectSerializer do
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'polymorphic throws an error that polymorphic is not supported' do
 | 
			
		||||
    it 'polymorphic has_many: returns correct nested includes when serializable_hash is called' do
 | 
			
		||||
      options = {}
 | 
			
		||||
      options[:include] = [:groupees]
 | 
			
		||||
      expect(-> { GroupSerializer.new([group], options)}).to raise_error(NotImplementedError)
 | 
			
		||||
 | 
			
		||||
      serializable_hash = GroupSerializer.new([group], options).serializable_hash
 | 
			
		||||
 | 
			
		||||
      persons_serialized = serializable_hash[:included].find_all { |included| included[:type] == :person }.map { |included| included[:id].to_i }
 | 
			
		||||
      groups_serialized = serializable_hash[:included].find_all { |included| included[:type] == :group }.map { |included| included[:id].to_i }
 | 
			
		||||
 | 
			
		||||
      persons = group.groupees.find_all { |groupee| groupee.is_a?(Person) }
 | 
			
		||||
      persons.each do |person|
 | 
			
		||||
        expect(persons_serialized).to include(person.id)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      groups = group.groupees.find_all { |groupee| groupee.is_a?(Group) }
 | 
			
		||||
      groups.each do |group|
 | 
			
		||||
        expect(groups_serialized).to include(group.id)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -310,6 +350,23 @@ describe FastJsonapi::ObjectSerializer do
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context 'when serializing included, params should be available in any serializer' do
 | 
			
		||||
    subject(:serializable_hash) do
 | 
			
		||||
      options = {}
 | 
			
		||||
      options[:include] = [:"actors.awards"]
 | 
			
		||||
      options[:params] = { include_award_year: true }
 | 
			
		||||
      MovieSerializer.new(movie, options).serializable_hash
 | 
			
		||||
    end
 | 
			
		||||
    let(:actor) { movie.actors.first }
 | 
			
		||||
    let(:award) { actor.awards.first }
 | 
			
		||||
    let(:year) { award.year }
 | 
			
		||||
 | 
			
		||||
    it 'passes params to deeply nested includes' do
 | 
			
		||||
      expect(year).to_not be_blank
 | 
			
		||||
      expect(serializable_hash[:included][0][:attributes][:year]).to eq year
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context 'when is_collection option present' do
 | 
			
		||||
    subject { MovieSerializer.new(resource, is_collection_options).serializable_hash }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -80,6 +80,8 @@ RSpec.shared_context 'movie class' do
 | 
			
		||||
            a.id = i
 | 
			
		||||
            a.title = "Test Award #{i}"
 | 
			
		||||
            a.actor_id = id
 | 
			
		||||
            a.imdb_award_id = i * 10
 | 
			
		||||
            a.year = 1990 + i
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
@ -110,7 +112,7 @@ RSpec.shared_context 'movie class' do
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    class Award
 | 
			
		||||
      attr_accessor :id, :title, :actor_id
 | 
			
		||||
      attr_accessor :id, :title, :actor_id, :year, :imdb_award_id
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    class State
 | 
			
		||||
@ -225,6 +227,11 @@ RSpec.shared_context 'movie class' do
 | 
			
		||||
    class AwardSerializer
 | 
			
		||||
      include FastJsonapi::ObjectSerializer
 | 
			
		||||
      attributes :id, :title
 | 
			
		||||
      attribute :year, if: Proc.new { |record, params|
 | 
			
		||||
        params[:include_award_year].present? ? 
 | 
			
		||||
          params[:include_award_year] : 
 | 
			
		||||
          false
 | 
			
		||||
      }
 | 
			
		||||
      belongs_to :actor
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user