module FastJsonapi::SerializationCore
Attributes
Public Instance Methods
# File lib/fast_jsonapi/serialization_core.rb, line 44 def attributes_hash(record, fieldset = nil, params = {}) attributes = attributes_to_serialize attributes = attributes.slice(*fieldset) if fieldset.present? attributes = {} if fieldset == [] attributes.each_with_object({}) do |(_k, attribute), hash| attribute.serialize(record, params, hash) end end
includes handler
# File lib/fast_jsonapi/serialization_core.rb, line 171 def get_included_records(record, includes_list, known_included_objects, fieldsets, params = {}) return unless includes_list.present? return [] unless relationships_to_serialize includes_list = parse_includes_list(includes_list) includes_list.each_with_object([]) do |include_item, included_records| relationship_item = relationships_to_serialize[include_item.first] next unless relationship_item&.include_relationship?(record, params) included_objects = Array(relationship_item.fetch_associated_object(record, params)) next if included_objects.empty? static_serializer = relationship_item.static_serializer static_record_type = relationship_item.static_record_type included_objects.each do |inc_obj| serializer = static_serializer || relationship_item.serializer_for(inc_obj, params) record_type = static_record_type || serializer.record_type if include_item.last.any? serializer_records = serializer.get_included_records(inc_obj, include_item.last, known_included_objects, fieldsets, params) included_records.concat(serializer_records) unless serializer_records.empty? end code = "#{record_type}_#{serializer.id_from_record(inc_obj, params)}" next if known_included_objects.include?(code) known_included_objects << code included_records << serializer.record_hash(inc_obj, fieldsets[record_type], includes_list, params) end end end
rubocop:enable Lint/UnusedMethodArgument
# File lib/fast_jsonapi/serialization_core.rb, line 122 def id_from_record(record, params) return FastJsonapi.call_proc(record_id, record, params) if record_id.is_a?(Proc) return record.send(record_id) if record_id raise MandatoryField, 'id is a mandatory field in the jsonapi spec' unless record.respond_to?(:id) record.id end
# File lib/fast_jsonapi/serialization_core.rb, line 30 def id_hash(id, record_type, default_return = false) if id.present? { id: id.to_s, type: record_type } else default_return ? { id: nil, type: record_type } : nil end end
# File lib/fast_jsonapi/serialization_core.rb, line 38 def links_hash(record, params = {}) data_links.each_with_object({}) do |(_k, link), hash| link.serialize(record, params, hash) end end
# File lib/fast_jsonapi/serialization_core.rb, line 65 def meta_hash(record, params = {}) FastJsonapi.call_proc(meta_to_serialize, record, params) end
It chops out the root association (first part) from each include.
It keeps an unique list and collects all of the rest of the include value to hand it off to the next related to include serializer.
This method will turn that include array into a Hash that looks like:
{ authors: Set.new([ 'books', 'books.genre', 'books.genre.books', 'books.genre.books.authors', 'books.genre.books.genre' ]), genre: Set.new(['books']) }
Because the serializer only cares about the root associations included, it only needs the first segment of each include (for books, it’s the “authors” and “genre”) and it doesn’t need to waste cycles parsing the rest of the include value. That will be done by the next serializer in line.
@param includes_list [List] to be parsed @return [Hash]
# File lib/fast_jsonapi/serialization_core.rb, line 162 def parse_includes_list(includes_list) includes_list.each_with_object({}) do |include_item, include_sets| include_base, include_remainder = include_item.to_s.split('.', 2) include_sets[include_base.to_sym] ||= Set.new include_sets[include_base.to_sym] << include_remainder if include_remainder end end
Cache options helper. Use it to adapt cache keys/rules.
If a fieldset is specified, it modifies the namespace to include the fields from the fieldset.
@param options [Hash] default cache options @param fieldset [Array, nil] passed fieldset values @param includes_list [Array, nil] passed included values @param params [Hash] the serializer params
@return [Hash] processed options hash rubocop:disable Lint/UnusedMethodArgument
# File lib/fast_jsonapi/serialization_core.rb, line 103 def record_cache_options(options, fieldset, includes_list, params) return options unless fieldset options = options ? options.dup : {} options[:namespace] ||= 'jsonapi-serializer' fieldset_key = fieldset.join('_') # Use a fixed-length fieldset key if the current length is more than # the length of a SHA1 digest if fieldset_key.length > 40 fieldset_key = Digest::SHA1.hexdigest(fieldset_key) end options[:namespace] = "#{options[:namespace]}-fieldset:#{fieldset_key}" options end
# File lib/fast_jsonapi/serialization_core.rb, line 69 def record_hash(record, fieldset, includes_list, params = {}) if cache_store_instance cache_opts = record_cache_options(cache_store_options, fieldset, includes_list, params) record_hash = cache_store_instance.fetch(record, **cache_opts) do temp_hash = id_hash(id_from_record(record, params), type_from_record(record, record_type), true) temp_hash[:attributes] = attributes_hash(record, fieldset, params) if attributes_to_serialize.present? temp_hash[:relationships] = relationships_hash(record, cachable_relationships_to_serialize, fieldset, includes_list, params) if cachable_relationships_to_serialize.present? 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, fieldset, includes_list, params)) if uncachable_relationships_to_serialize.present? else record_hash = id_hash(id_from_record(record, params), type_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, includes_list, params) if relationships_to_serialize.present? record_hash[:links] = links_hash(record, params) if data_links.present? end record_hash[:meta] = meta_hash(record, params) if meta_to_serialize.present? record_hash end
# File lib/fast_jsonapi/serialization_core.rb, line 54 def relationships_hash(record, relationships = nil, fieldset = nil, includes_list = nil, params = {}) relationships = relationships_to_serialize if relationships.nil? relationships = relationships.slice(*fieldset) if fieldset.present? relationships = {} if fieldset == [] relationships.each_with_object({}) do |(key, relationship), hash| included = includes_list.present? && includes_list.include?(key) relationship.serialize(record, included, params, hash) end end
# File lib/fast_jsonapi/serialization_core.rb, line 130 def type_from_record(record, record_type) return FastJsonapi.call_proc(record_type_block, record) if record_type_block.is_a?(Proc) record_type end