mirror of
https://github.com/ditkrg/jsonapi-deserializable.git
synced 2026-01-22 13:56:50 +00:00
Initial commit
This commit is contained in:
commit
2443af13cb
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
*.gem
|
||||
*.rbc
|
||||
/.config
|
||||
/coverage/
|
||||
/InstalledFiles
|
||||
/pkg/
|
||||
/spec/reports/
|
||||
/spec/examples.txt
|
||||
/test/tmp/
|
||||
/test/version_tmp/
|
||||
/tmp/
|
||||
|
||||
## Specific to RubyMotion:
|
||||
.dat*
|
||||
.repl_history
|
||||
build/
|
||||
|
||||
## Documentation cache and generated files:
|
||||
/.yardoc/
|
||||
/_yardoc/
|
||||
/doc/
|
||||
/rdoc/
|
||||
|
||||
## Environment normalization:
|
||||
/.bundle/
|
||||
/vendor/bundle
|
||||
/lib/bundler/man/
|
||||
|
||||
Gemfile.lock
|
||||
.ruby-version
|
||||
.ruby-gemset
|
||||
|
||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||
.rvmrc
|
||||
12
.travis.yml
Normal file
12
.travis.yml
Normal file
@ -0,0 +1,12 @@
|
||||
language: ruby
|
||||
sudo: false
|
||||
before_install:
|
||||
- bundle update
|
||||
rvm:
|
||||
- 2.1
|
||||
- 2.2
|
||||
- 2.3.0
|
||||
- ruby-head
|
||||
matrix:
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
234
README.md
Normal file
234
README.md
Normal file
@ -0,0 +1,234 @@
|
||||
# jsonapi-deserializable
|
||||
Ruby gem for deserializing [JSON API](http://jsonapi.org) payloads into custom
|
||||
hashes.
|
||||
|
||||
## Status
|
||||
|
||||
[](https://badge.fury.io/rb/jsonapi-deserializable)
|
||||
[](http://travis-ci.org/jsonapi-rb/deserializable?branch=master)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Usage/Examples](#usageexamples)
|
||||
- [Documentation](#documentation)
|
||||
- [Common methods](#common-methods)
|
||||
- [`JSONAPI::Deserializable::Resource` DSL](#jsonapideserializableresource-dsl)
|
||||
- [`JSONAPI::Deserializable::Relationship` DSL](#jsonapideserializablerelationship-dsl)
|
||||
- [License](#license)
|
||||
|
||||
## Installation
|
||||
```ruby
|
||||
# In Gemfile
|
||||
gem 'jsonapi-deserializable'
|
||||
```
|
||||
then
|
||||
```
|
||||
$ bundle
|
||||
```
|
||||
or manually via
|
||||
```
|
||||
$ gem install jsonapi-deserializable
|
||||
```
|
||||
|
||||
## Usage/Examples
|
||||
|
||||
First, require the gem:
|
||||
```ruby
|
||||
require 'jsonapi/deserializable'
|
||||
```
|
||||
|
||||
Then, define some resource/relationship deserializable classes:
|
||||
|
||||
### Resource Example
|
||||
|
||||
```ruby
|
||||
class DeserializablePost < JSONAPI::Deserializable::Resource
|
||||
type
|
||||
attribute :title
|
||||
attribute :date { |date| field date: DateTime.parse(date) }
|
||||
has_one :author do |rel, id, type|
|
||||
field author_id: id
|
||||
field author_type: type
|
||||
end
|
||||
has_many :comments do |rel, ids, types|
|
||||
field comment_ids: ids
|
||||
field comment_types: types.map do |type|
|
||||
camelize(singularize(type))
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
which can then be used to deserialize post payloads:
|
||||
```ruby
|
||||
DeserializablePost.(payload)
|
||||
# => {
|
||||
# id: '1',
|
||||
# title: 'Title',
|
||||
# date: #<DateTime: 2016-01-10T02:30:00+00:00 ((2457398j,9000s,0n),+0s,2299161j)>,
|
||||
# author_id: '1337',
|
||||
# author_type: 'users',
|
||||
# comment_ids: ['123', '234', '345']
|
||||
# comment_types: ['Comment', 'Comment', 'Comment']
|
||||
# }
|
||||
```
|
||||
|
||||
### Relationship Example
|
||||
|
||||
```ruby
|
||||
class DeserializablePostComments < JSONAPI::Deserializable::Relationship
|
||||
has_many do |rel, ids, types|
|
||||
field comment_ids: ids
|
||||
field comment_types: types.map do |ri|
|
||||
camelize(singularize(type))
|
||||
end
|
||||
field comments_meta: rel['meta']
|
||||
end
|
||||
end
|
||||
```
|
||||
```ruby
|
||||
DeserializablePostComments.(payload)
|
||||
# => {
|
||||
# comment_ids: ['123', '234', '345']
|
||||
# comment_types: ['Comment', 'Comment', 'Comment']
|
||||
# }
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Whether deserializaing a resource or a relationship, the base idea is the same:
|
||||
for every part of the payload, simply declare the fields you want to build from
|
||||
their value. You can create as many fields as you want out of any one part of
|
||||
the payload.
|
||||
|
||||
It works according to a whitelisting mechanism: should the corresponding part of
|
||||
the payload not be present, the fields will simply not be created on the result
|
||||
hash.
|
||||
|
||||
Note however that the library expects well formed JSONAPI payloads (which you
|
||||
can ensure using, for instance,
|
||||
[jsonapi-parser](https://github.com/beauby/jsonapi/tree/master/parser)),
|
||||
and that deserialization does not substitute itself to validation of the
|
||||
resulting hash (which you can handle using, for instance,
|
||||
[dry-validation](http://dry-rb.org/gems/dry-validation/)).
|
||||
|
||||
### Common Methods
|
||||
|
||||
+ `::field(hash)`
|
||||
|
||||
The `field` DSL method is the base of jsonapi-deserializable. It simply declares
|
||||
a field of the result hash, with its value. The syntax is:
|
||||
```ruby
|
||||
field key: value
|
||||
```
|
||||
|
||||
It is mainly used within the following DSL contexts, but can be used outside of
|
||||
any to declare custom non payload-related fields.
|
||||
|
||||
+ `#initialize(payload)`
|
||||
|
||||
Build a deserializable instance, ready to be deserialized by calling `#to_h`.
|
||||
|
||||
+ `#to_h`
|
||||
|
||||
In order to deserialize a payload, simply do:
|
||||
```ruby
|
||||
DeserializablePost.new(payload).to_h
|
||||
```
|
||||
or use the shorthand syntax:
|
||||
```ruby
|
||||
DeserializablePost.(payload)
|
||||
```
|
||||
|
||||
### `JSONAPI::Deserializable::Resource` DSL
|
||||
|
||||
+ `::type(&block)`
|
||||
```ruby
|
||||
type do |type|
|
||||
field my_type_field: type
|
||||
end
|
||||
```
|
||||
|
||||
Shorthand syntax:
|
||||
```ruby
|
||||
type
|
||||
```
|
||||
|
||||
+ `::id(&block)`
|
||||
```ruby
|
||||
id do |id|
|
||||
field my_id_field: id
|
||||
end
|
||||
```
|
||||
|
||||
Shorthand syntax:
|
||||
```ruby
|
||||
id
|
||||
```
|
||||
|
||||
+ `::attribute(key, &block)`
|
||||
```ruby
|
||||
attribute :title do |title|
|
||||
field my_title_field: title
|
||||
end
|
||||
```
|
||||
|
||||
Shorthand syntax:
|
||||
```ruby
|
||||
attribute :title
|
||||
```
|
||||
|
||||
+ `::has_one(key, &block)`
|
||||
```ruby
|
||||
has_one :author do |rel, id, type|
|
||||
field my_author_type_field: type
|
||||
field my_author_id_field: id
|
||||
field my_author_meta_field: rel['meta']
|
||||
end
|
||||
```
|
||||
|
||||
Shorthand syntax:
|
||||
```ruby
|
||||
has_one :author
|
||||
```
|
||||
Note: this creates a field `:author` with value the whole relationship hash.
|
||||
|
||||
+ `::has_many(key, &block)`
|
||||
```ruby
|
||||
has_many :comments do |rel, ids, types|
|
||||
field my_comment_types_field: types
|
||||
field my_comment_ids_field: ids
|
||||
field my_comment_meta_field: rel['meta']
|
||||
end
|
||||
```
|
||||
|
||||
Shorthand syntax:
|
||||
```ruby
|
||||
has_many :comments
|
||||
```
|
||||
Note: this creates a field `:comments` with value the whole relationship hash.
|
||||
|
||||
### `JSONAPI::Deserializable::Relationship` DSL
|
||||
|
||||
+ `::has_one(key, &block)`
|
||||
```ruby
|
||||
has_one do |rel, id, type|
|
||||
field my_relationship_id_field: id
|
||||
field my_relationship_type_field: type
|
||||
field my_relationship_meta_field: rel['meta']
|
||||
end
|
||||
```
|
||||
|
||||
+ `has_many(key, &block)`
|
||||
```ruby
|
||||
has_many do |rel, ids, types|
|
||||
field my_relationship_ids_field: ids
|
||||
field my_relationship_types_field: types
|
||||
field my_relationship_meta_field: rel['meta']
|
||||
end
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
jsonapi-deserializable is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
||||
9
Rakefile
Normal file
9
Rakefile
Normal file
@ -0,0 +1,9 @@
|
||||
require 'bundler/gem_tasks'
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec) do |t|
|
||||
t.pattern = Dir.glob('spec/**/*_spec.rb')
|
||||
end
|
||||
|
||||
task default: :test
|
||||
task test: :spec
|
||||
19
jsonapi-deserializable.gemspec
Normal file
19
jsonapi-deserializable.gemspec
Normal file
@ -0,0 +1,19 @@
|
||||
version = File.read(File.expand_path('../VERSION', __FILE__)).strip
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'jsonapi-deserializable'
|
||||
spec.version = version
|
||||
spec.author = 'Lucas Hosseini'
|
||||
spec.email = 'lucas.hosseini@gmail.com'
|
||||
spec.summary = 'Deserialize JSON API payloads.'
|
||||
spec.description = 'DSL for deserializing incoming JSON API payloads ' \
|
||||
'into custom hashes.'
|
||||
spec.homepage = 'https://github.com/jsonapi-rb/deserializable'
|
||||
spec.license = 'MIT'
|
||||
|
||||
spec.files = Dir['README.md', 'lib/**/*']
|
||||
spec.require_path = 'lib'
|
||||
|
||||
spec.add_development_dependency 'rake', '>=0.9'
|
||||
spec.add_development_dependency 'rspec', '~>3.4'
|
||||
end
|
||||
2
lib/jsonapi/deserializable.rb
Normal file
2
lib/jsonapi/deserializable.rb
Normal file
@ -0,0 +1,2 @@
|
||||
require 'jsonapi/deserializable/relationship'
|
||||
require 'jsonapi/deserializable/resource'
|
||||
51
lib/jsonapi/deserializable/relationship.rb
Normal file
51
lib/jsonapi/deserializable/relationship.rb
Normal file
@ -0,0 +1,51 @@
|
||||
require 'jsonapi/deserializable/relationship_dsl'
|
||||
|
||||
module JSONAPI
|
||||
module Deserializable
|
||||
class Relationship
|
||||
include RelationshipDSL
|
||||
|
||||
class << self
|
||||
attr_accessor :has_one_block, :has_many_block
|
||||
end
|
||||
|
||||
def self.inherited(klass)
|
||||
klass.has_one_block = has_one_block
|
||||
klass.has_many_block = has_many_block
|
||||
end
|
||||
|
||||
def self.call(payload)
|
||||
new(payload).to_h
|
||||
end
|
||||
|
||||
def initialize(payload)
|
||||
@document = payload
|
||||
@data = payload['data']
|
||||
deserialize!
|
||||
end
|
||||
|
||||
def to_h
|
||||
@hash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deserialize!
|
||||
@hash = {}
|
||||
if @data.is_a?(Array)
|
||||
ids = @data.map { |ri| ri['id'] }
|
||||
types = @data.map { |ri| ri['type'] }
|
||||
instance_exec(@document, ids, types, &self.class.has_many_block)
|
||||
else
|
||||
id = @data && @data['id']
|
||||
type = @data && @data['type']
|
||||
instance_exec(@document, id, type, &self.class.has_one_block)
|
||||
end
|
||||
end
|
||||
|
||||
def field(hash)
|
||||
@hash.merge!(hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
21
lib/jsonapi/deserializable/relationship_dsl.rb
Normal file
21
lib/jsonapi/deserializable/relationship_dsl.rb
Normal file
@ -0,0 +1,21 @@
|
||||
module JSONAPI
|
||||
module Deserializable
|
||||
module RelationshipDSL
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def has_one(&block)
|
||||
block ||= proc { |rel| field key.to_sym => rel }
|
||||
self.has_one_block = block
|
||||
end
|
||||
|
||||
def has_many(&block)
|
||||
block ||= proc { |rel| field key.to_sym => rel }
|
||||
self.has_many_block = block
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
110
lib/jsonapi/deserializable/resource.rb
Normal file
110
lib/jsonapi/deserializable/resource.rb
Normal file
@ -0,0 +1,110 @@
|
||||
require 'jsonapi/deserializable/resource_dsl'
|
||||
|
||||
module JSONAPI
|
||||
module Deserializable
|
||||
class Resource
|
||||
include ResourceDSL
|
||||
|
||||
class << self
|
||||
attr_accessor :type_block, :id_block
|
||||
attr_accessor :attr_blocks
|
||||
attr_accessor :has_one_rel_blocks, :has_many_rel_blocks
|
||||
end
|
||||
|
||||
self.attr_blocks = {}
|
||||
self.has_one_rel_blocks = {}
|
||||
self.has_many_rel_blocks = {}
|
||||
|
||||
def self.inherited(klass)
|
||||
super
|
||||
klass.type_block = type_block
|
||||
klass.id_block = id_block
|
||||
klass.attr_blocks = attr_blocks.dup
|
||||
klass.has_one_rel_blocks = has_one_rel_blocks.dup
|
||||
klass.has_many_rel_blocks = has_many_rel_blocks.dup
|
||||
end
|
||||
|
||||
def self.call(payload)
|
||||
new(payload).to_h
|
||||
end
|
||||
|
||||
def initialize(payload)
|
||||
@document = payload
|
||||
@data = @document['data']
|
||||
@type = @data['type']
|
||||
@id = @data['id']
|
||||
@attributes = @data['attributes'] || {}
|
||||
@relationships = @data['relationships'] || {}
|
||||
deserialize!
|
||||
end
|
||||
|
||||
def to_h
|
||||
@hash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deserialize!
|
||||
@hash = {}
|
||||
deserialize_type!
|
||||
deserialize_id!
|
||||
deserialize_attrs!
|
||||
deserialize_rels!
|
||||
end
|
||||
|
||||
def deserialize_type!
|
||||
return unless @type && self.class.type_block
|
||||
instance_exec(@type, &self.class.type_block)
|
||||
end
|
||||
|
||||
def deserialize_id!
|
||||
return unless @id && self.class.id_block
|
||||
instance_exec(@id, &self.class.id_block)
|
||||
end
|
||||
|
||||
def deserialize_attrs!
|
||||
self.class.attr_blocks.each do |attr, block|
|
||||
next unless @attributes.key?(attr)
|
||||
instance_exec(@attributes[attr], &block)
|
||||
end
|
||||
end
|
||||
|
||||
def deserialize_rels!
|
||||
deserialize_has_one_rels!
|
||||
deserialize_has_many_rels!
|
||||
end
|
||||
|
||||
def deserialize_has_one_rels!
|
||||
self.class.has_one_rel_blocks.each do |key, block|
|
||||
rel = @relationships[key]
|
||||
next unless rel && (rel['data'].nil? || rel['data'].is_a?(Hash))
|
||||
deserialize_has_one_rel!(rel, &block)
|
||||
end
|
||||
end
|
||||
|
||||
def deserialize_has_one_rel!(rel, &block)
|
||||
id = rel['data'] && rel['data']['id']
|
||||
type = rel['data'] && rel['data']['type']
|
||||
instance_exec(rel, id, type, &block)
|
||||
end
|
||||
|
||||
def deserialize_has_many_rels!
|
||||
self.class.has_many_rel_blocks.each do |key, block|
|
||||
rel = @relationships[key]
|
||||
next unless rel && rel['data'].is_a?(Array)
|
||||
deserialize_has_many_rel!(rel, &block)
|
||||
end
|
||||
end
|
||||
|
||||
def deserialize_has_many_rel!(rel, &block)
|
||||
ids = rel['data'].map { |ri| ri['id'] }
|
||||
types = rel['data'].map { |ri| ri['type'] }
|
||||
instance_exec(rel, ids, types, &block)
|
||||
end
|
||||
|
||||
def field(hash)
|
||||
@hash.merge!(hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
39
lib/jsonapi/deserializable/resource_dsl.rb
Normal file
39
lib/jsonapi/deserializable/resource_dsl.rb
Normal file
@ -0,0 +1,39 @@
|
||||
module JSONAPI
|
||||
module Deserializable
|
||||
module ResourceDSL
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def type(&block)
|
||||
block ||= proc { |type| field type: type }
|
||||
self.type_block = block
|
||||
end
|
||||
|
||||
def id(&block)
|
||||
block ||= proc { |id| field id: id }
|
||||
self.id_block = block
|
||||
end
|
||||
|
||||
def attribute(key, options = {}, &block)
|
||||
unless block
|
||||
options[:key] ||= key.to_sym
|
||||
block = proc { |attr| field key => attr }
|
||||
end
|
||||
attr_blocks[key.to_s] = block
|
||||
end
|
||||
|
||||
def has_one(key, &block)
|
||||
block ||= proc { |rel| field key.to_sym => rel }
|
||||
has_one_rel_blocks[key.to_s] = block
|
||||
end
|
||||
|
||||
def has_many(key, &block)
|
||||
block ||= proc { |rel| field key.to_sym => rel }
|
||||
has_many_rel_blocks[key.to_s] = block
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
44
spec/deserializable_relationships_spec.rb
Normal file
44
spec/deserializable_relationships_spec.rb
Normal file
@ -0,0 +1,44 @@
|
||||
require 'jsonapi/deserializable'
|
||||
|
||||
describe JSONAPI::Deserializable::Relationship, '#to_h' do
|
||||
it 'deserializes has_one relationships' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Relationship) do
|
||||
has_one do |rel|
|
||||
field sponsor_id: (rel['data'] && rel['data']['id'])
|
||||
end
|
||||
end
|
||||
|
||||
payload = {
|
||||
'data' => {
|
||||
'type' => 'users',
|
||||
'id' => '1'
|
||||
}
|
||||
}
|
||||
|
||||
actual = deserializable_klass.(payload)
|
||||
expected = { sponsor_id: '1' }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it 'deserializes has_many relationships' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Relationship) do
|
||||
has_many do |rel|
|
||||
field post_ids: rel['data'].map { |ri| ri['id'] }
|
||||
end
|
||||
end
|
||||
|
||||
payload = {
|
||||
'data' => [
|
||||
{ 'type' => 'postd', 'id' => '1' },
|
||||
{ 'type' => 'postd', 'id' => '2' },
|
||||
{ 'type' => 'postd', 'id' => '3' }
|
||||
]
|
||||
}
|
||||
|
||||
actual = deserializable_klass.(payload)
|
||||
expected = { post_ids: %w(1 2 3) }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
end
|
||||
132
spec/deserializable_resource_spec.rb
Normal file
132
spec/deserializable_resource_spec.rb
Normal file
@ -0,0 +1,132 @@
|
||||
require 'jsonapi/deserializable'
|
||||
|
||||
describe JSONAPI::Deserializable::Resource, '#to_h' do
|
||||
before(:all) do
|
||||
@payload = {
|
||||
'data' => {
|
||||
'id' => '1',
|
||||
'type' => 'users',
|
||||
'attributes' => {
|
||||
'name' => 'Name',
|
||||
'address' => 'Address'
|
||||
},
|
||||
'relationships' => {
|
||||
'sponsor' => {
|
||||
'data' => { 'type' => 'users', 'id' => '1337' }
|
||||
},
|
||||
'posts' => {
|
||||
'data' => [
|
||||
{ 'type' => 'posts', 'id' => '123' },
|
||||
{ 'type' => 'posts', 'id' => '234' },
|
||||
{ 'type' => 'posts', 'id' => '345' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'deserializes primary type' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
type { |type| field type: type }
|
||||
end
|
||||
|
||||
actual = deserializable_klass.(@payload)
|
||||
expected = { type: 'users' }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it 'deserializes primary id when present' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id { |id| field id: id }
|
||||
end
|
||||
|
||||
actual = deserializable_klass.(@payload)
|
||||
expected = { id: '1' }
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it 'does not deserialize primary id when absent' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id { |id| field id: id }
|
||||
end
|
||||
|
||||
payload = {
|
||||
'data' => { 'type' => 'users' }
|
||||
}
|
||||
actual = deserializable_klass.(payload)
|
||||
expected = {}
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it 'handles attributes' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
attribute(:name) { |name| field username: name }
|
||||
attribute(:address) { |address| field address: address }
|
||||
end
|
||||
|
||||
actual = deserializable_klass.(@payload)
|
||||
expected = {
|
||||
username: 'Name',
|
||||
address: 'Address'
|
||||
}
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it 'handles has_one relationships' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
has_one(:sponsor) { |rel| field sponsor_id: rel['data']['id'] }
|
||||
end
|
||||
|
||||
actual = deserializable_klass.(@payload)
|
||||
expected = {
|
||||
sponsor_id: '1337'
|
||||
}
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it 'handles has_many relationships' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
has_many(:posts) do |rel|
|
||||
field post_ids: rel['data'].map { |ri| ri['id'] }
|
||||
end
|
||||
end
|
||||
|
||||
actual = deserializable_klass.(@payload)
|
||||
expected = {
|
||||
post_ids: %w(123 234 345)
|
||||
}
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it 'works' do
|
||||
deserializable_klass = Class.new(JSONAPI::Deserializable::Resource) do
|
||||
id
|
||||
attribute(:name) { |name| field username: name }
|
||||
attribute :address
|
||||
has_one :sponsor do |_, id|
|
||||
field sponsor_id: id
|
||||
end
|
||||
has_many :posts do |_, ids|
|
||||
field post_ids: ids
|
||||
end
|
||||
end
|
||||
|
||||
actual = deserializable_klass.(@payload)
|
||||
expected = {
|
||||
id: '1',
|
||||
username: 'Name',
|
||||
address: 'Address',
|
||||
sponsor_id: '1337',
|
||||
post_ids: %w(123 234 345)
|
||||
}
|
||||
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user