add is_collection parameter to force corresponding serialization (#239)
* add is_collection parameter to force corresponding serialization * add documentation for is_collection purpose, behavior and notes re. default autodetect logic
This commit is contained in:
parent
af38b30179
commit
ecb92f07f5
20
README.md
20
README.md
@ -261,6 +261,26 @@ hash = MovieSerializer.new([movie, movie], options).serializable_hash
|
||||
json_string = MovieSerializer.new([movie, movie], options).serialized_json
|
||||
```
|
||||
|
||||
#### Control Over Collection Serialization
|
||||
|
||||
You can use `is_collection` option to have better control over collection serialization.
|
||||
|
||||
If this option is not provided or `nil` autedetect logic is used to try understand
|
||||
if provided resource is a single object or collection.
|
||||
|
||||
Autodetect logic is compatible with most DB toolkits (ActiveRecord, Sequel, etc.) but
|
||||
**cannot** guarantee that single vs collection will be always detected properly.
|
||||
|
||||
```ruby
|
||||
options[:is_collection]
|
||||
```
|
||||
|
||||
was introduced to be able to have precise control this behavior
|
||||
|
||||
- `nil` or not provided: will try to autodetect single vs collection (please, see notes above)
|
||||
- `true` will always treat input resource as *collection*
|
||||
- `false` will always treat input resource as *single object*
|
||||
|
||||
### Caching
|
||||
Requires a `cache_key` method be defined on model:
|
||||
|
||||
|
@ -28,7 +28,7 @@ module FastJsonapi
|
||||
end
|
||||
|
||||
def serializable_hash
|
||||
return hash_for_collection if is_collection?(@resource)
|
||||
return hash_for_collection if is_collection?(@resource, @is_collection)
|
||||
|
||||
hash_for_one_record
|
||||
end
|
||||
@ -75,6 +75,7 @@ module FastJsonapi
|
||||
@known_included_objects = {}
|
||||
@meta = options[:meta]
|
||||
@links = options[:links]
|
||||
@is_collection = options[:is_collection]
|
||||
@params = options[:params] || {}
|
||||
raise ArgumentError.new("`params` option passed to serializer must be a hash") unless @params.is_a?(Hash)
|
||||
|
||||
@ -84,8 +85,10 @@ module FastJsonapi
|
||||
end
|
||||
end
|
||||
|
||||
def is_collection?(resource)
|
||||
resource.respond_to?(:each) && !resource.respond_to?(:each_pair)
|
||||
def is_collection?(resource, force_is_collection = nil)
|
||||
return force_is_collection unless force_is_collection.nil?
|
||||
|
||||
resource.respond_to?(:size) && !resource.respond_to?(:each_pair)
|
||||
end
|
||||
|
||||
class_methods do
|
||||
|
@ -310,6 +310,52 @@ describe FastJsonapi::ObjectSerializer do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when is_collection option present' do
|
||||
subject { MovieSerializer.new(resource, is_collection_options).serializable_hash }
|
||||
|
||||
context 'autodetect' do
|
||||
let(:is_collection_options) { {} }
|
||||
|
||||
context 'collection if no option present' do
|
||||
let(:resource) { [movie] }
|
||||
it { expect(subject[:data]).to be_a(Array) }
|
||||
end
|
||||
|
||||
context 'single if no option present' do
|
||||
let(:resource) { movie }
|
||||
it { expect(subject[:data]).to be_a(Hash) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'force is_collection to true' do
|
||||
let(:is_collection_options) { { is_collection: true } }
|
||||
|
||||
context 'collection will pass' do
|
||||
let(:resource) { [movie] }
|
||||
it { expect(subject[:data]).to be_a(Array) }
|
||||
end
|
||||
|
||||
context 'single will raise error' do
|
||||
let(:resource) { movie }
|
||||
it { expect { subject }.to raise_error(NoMethodError, /method(.*)each/) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'force is_collection to false' do
|
||||
let(:is_collection_options) { { is_collection: false } }
|
||||
|
||||
context 'collection will fail without id' do
|
||||
let(:resource) { [movie] }
|
||||
it { expect { subject }.to raise_error(FastJsonapi::MandatoryField, /id is a mandatory field/) }
|
||||
end
|
||||
|
||||
context 'single will pass' do
|
||||
let(:resource) { movie }
|
||||
it { expect(subject[:data]).to be_a(Hash) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when optional attributes are determined by record data' do
|
||||
it 'returns optional attribute when attribute is included' do
|
||||
movie.release_year = 2001
|
||||
|
Loading…
x
Reference in New Issue
Block a user