-
Notifications
You must be signed in to change notification settings - Fork 421
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module FastJsonapi | ||
class Fieldset | ||
def initialize(fields) | ||
@fields = fields | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,8 @@ class << self | |
:cache_length, | ||
:race_condition_ttl, | ||
:cached, | ||
:data_links | ||
:data_links, | ||
:fieldset | ||
end | ||
end | ||
|
||
|
@@ -40,36 +41,39 @@ def links_hash(record, params = {}) | |
end | ||
end | ||
|
||
def attributes_hash(record, params = {}) | ||
attributes_to_serialize.each_with_object({}) do |(_k, attribute), hash| | ||
def attributes_hash(record, fieldset = nil, params = {}) | ||
attributes = attributes_to_serialize | ||
attributes = attributes.slice(*fieldset) if fieldset.present? | ||
attributes.each_with_object({}) do |(_k, attribute), hash| | ||
attribute.serialize(record, params, hash) | ||
end | ||
end | ||
|
||
def relationships_hash(record, relationships = nil, params = {}) | ||
def relationships_hash(record, relationships = nil, fieldset = nil, params = {}) | ||
relationships = relationships_to_serialize if relationships.nil? | ||
relationships = relationships.slice(*fieldset) if fieldset.present? | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
everlast240
|
||
|
||
relationships.each_with_object({}) do |(_k, relationship), hash| | ||
relationship.serialize(record, params, hash) | ||
end | ||
end | ||
|
||
def record_hash(record, params = {}) | ||
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 | ||
temp_hash = id_hash(id_from_record(record), record_type, true) | ||
temp_hash[:attributes] = attributes_hash(record, params) if attributes_to_serialize.present? | ||
temp_hash[:attributes] = attributes_hash(record, fieldset, params) if attributes_to_serialize.present? | ||
temp_hash[:relationships] = {} | ||
temp_hash[:relationships] = relationships_hash(record, cachable_relationships_to_serialize, params) if cachable_relationships_to_serialize.present? | ||
temp_hash[:relationships] = relationships_hash(record, cachable_relationships_to_serialize, fieldset, 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, params)) if uncachable_relationships_to_serialize.present? | ||
record_hash | ||
else | ||
record_hash = id_hash(id_from_record(record), record_type, true) | ||
record_hash[:attributes] = attributes_hash(record, params) if attributes_to_serialize.present? | ||
record_hash[:relationships] = relationships_hash(record, nil, params) if relationships_to_serialize.present? | ||
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 | ||
end | ||
|
@@ -100,7 +104,7 @@ def remaining_items(items) | |
end | ||
|
||
# includes handler | ||
def get_included_records(record, includes_list, known_included_objects, params = {}) | ||
def get_included_records(record, includes_list, known_included_objects, fieldsets, params = {}) | ||
return unless includes_list.present? | ||
|
||
includes_list.sort.each_with_object([]) do |include_item, included_records| | ||
|
@@ -120,15 +124,16 @@ def get_included_records(record, includes_list, known_included_objects, params = | |
|
||
included_objects.each do |inc_obj| | ||
if remaining_items(items) | ||
serializer_records = serializer.get_included_records(inc_obj, remaining_items(items), known_included_objects) | ||
serializer_records = serializer.get_included_records(inc_obj, remaining_items(items), known_included_objects, fieldsets) | ||
included_records.concat(serializer_records) unless serializer_records.empty? | ||
end | ||
|
||
code = "#{record_type}_#{inc_obj.id}" | ||
next if known_included_objects.key?(code) | ||
|
||
known_included_objects[code] = inc_obj | ||
included_records << serializer.record_hash(inc_obj, params) | ||
|
||
included_records << serializer.record_hash(inc_obj, fieldsets[serializer.reflected_record_type], params) | ||
end | ||
end | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
require 'spec_helper' | ||
|
||
describe FastJsonapi::ObjectSerializer do | ||
include_context 'movie class' | ||
|
||
let(:fields) do | ||
{ | ||
movie: %i[name actors], | ||
actor: %i[name agency] | ||
} | ||
end | ||
|
||
it 'only returns specified fields' do | ||
hash = MovieSerializer.new(movie, fields: fields).serializable_hash | ||
|
||
expect(hash[:data][:attributes].keys.sort).to eq %i[name] | ||
end | ||
|
||
it 'only returns specified relationships' do | ||
hash = MovieSerializer.new(movie, fields: fields).serializable_hash | ||
|
||
expect(hash[:data][:relationships].keys.sort).to eq %i[actors] | ||
end | ||
|
||
it 'only returns specified fields for included relationships' do | ||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors]).serializable_hash | ||
|
||
expect(hash[:included].first[:attributes].keys.sort).to eq %i[name] | ||
end | ||
|
||
it 'only returns specified relationships for included relationships' do | ||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors]).serializable_hash | ||
|
||
expect(hash[:included].first[:relationships].keys.sort).to eq %i[agency] | ||
end | ||
end |
What's this needed for here? And what do relationships have to do with sparse fieldsets?
In fact, I've identified this line as causing a bug (pretty critical actually): if you have sparse fieldsets (fields in the request), relationships key remains empty and when returning multiple results, you have no way how to link included resources (
include
clause) to the proper root resource in a compound document.Commenting it out seems to resolve this issue...