jsonapi 0.1.1.beta1 → 0.1.1.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -13
- data/README.md +1 -9
- data/jsonapi_parser.gemspec +0 -1
- data/lib/jsonapi/include_directive/parser.rb +13 -4
- data/lib/jsonapi/resource.rb +0 -2
- data/lib/jsonapi/version.rb +1 -1
- metadata +2 -19
- data/lib/jsonapi/resource/active_record.rb +0 -151
- data/spec/resource/to_activerecord_hash_spec.rb +0 -76
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ced99ef009aee2a4a5473acbc9ee8dc8c53d14b0
|
4
|
+
data.tar.gz: a9b87f7ef84013e382df467138ebc723790d27d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b0c8e23de976228e9a08d350d23459d49159422b329c72487261785490f548fa70a14556985d06cb2070c184bbebd1aad0a45505bd482e6ff3710111298f343
|
7
|
+
data.tar.gz: 6f85d5fe158aa995aa4059166e1143dd7826ddce93d0968aea9e1b7c8f289f4cfc24ab9c9a9c0733d44293d4a5d7df2242ab173e21bc16b0c7552d77493e3876
|
data/Gemfile.lock
CHANGED
@@ -1,23 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
jsonapi (0.1.1.
|
5
|
-
activesupport (>= 3.0)
|
4
|
+
jsonapi (0.1.1.beta2)
|
6
5
|
json (~> 1.8)
|
7
6
|
|
8
7
|
GEM
|
9
8
|
remote: https://rubygems.org/
|
10
9
|
specs:
|
11
|
-
activesupport (4.2.6)
|
12
|
-
i18n (~> 0.7)
|
13
|
-
json (~> 1.7, >= 1.7.7)
|
14
|
-
minitest (~> 5.1)
|
15
|
-
thread_safe (~> 0.3, >= 0.3.4)
|
16
|
-
tzinfo (~> 1.1)
|
17
10
|
diff-lcs (1.2.5)
|
18
|
-
i18n (0.7.0)
|
19
11
|
json (1.8.3)
|
20
|
-
minitest (5.8.4)
|
21
12
|
rake (11.1.2)
|
22
13
|
rspec (3.4.0)
|
23
14
|
rspec-core (~> 3.4.0)
|
@@ -32,9 +23,6 @@ GEM
|
|
32
23
|
diff-lcs (>= 1.2.0, < 2.0)
|
33
24
|
rspec-support (~> 3.4.0)
|
34
25
|
rspec-support (3.4.1)
|
35
|
-
thread_safe (0.3.5)
|
36
|
-
tzinfo (1.2.2)
|
37
|
-
thread_safe (~> 0.1)
|
38
26
|
|
39
27
|
PLATFORMS
|
40
28
|
ruby
|
data/README.md
CHANGED
@@ -40,14 +40,6 @@ include_directive = JSONAPI::IncludeDirective.new(include_args)
|
|
40
40
|
# Should the document be invalid, the parse method would fail with an
|
41
41
|
# InvalidDocument error.
|
42
42
|
|
43
|
-
document.data.to_activerecord_hash
|
44
|
-
# => {
|
45
|
-
# id: '1',
|
46
|
-
# title: 'JSON API paints my bikeshed!',
|
47
|
-
# author_id: '9',
|
48
|
-
# comment_ids: ['5', '12']
|
49
|
-
# }
|
50
|
-
|
51
43
|
document.data.links.defined?(:self)
|
52
44
|
# => true
|
53
45
|
document.data.links.self.value
|
@@ -135,7 +127,7 @@ Notes:
|
|
135
127
|
|
136
128
|
## License
|
137
129
|
|
138
|
-
|
130
|
+
jsonapi is Copyright © 2016 Lucas Hosseini.
|
139
131
|
|
140
132
|
It is free software, and may be redistributed under the terms specified in the
|
141
133
|
[LICENSE](LICENSE) file.
|
data/jsonapi_parser.gemspec
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/hash/deep_merge'
|
2
|
-
|
3
1
|
module JSONAPI
|
4
2
|
class IncludeDirective
|
5
3
|
# Utilities to create an IncludeDirective hash from various types of
|
@@ -28,7 +26,7 @@ module JSONAPI
|
|
28
26
|
include_string.split(',')
|
29
27
|
.map(&:strip)
|
30
28
|
.each_with_object({}) do |path, hash|
|
31
|
-
|
29
|
+
deep_merge!(hash, parse_path_string(path))
|
32
30
|
end
|
33
31
|
end
|
34
32
|
|
@@ -49,7 +47,18 @@ module JSONAPI
|
|
49
47
|
# @api private
|
50
48
|
def parse_array(include_array)
|
51
49
|
include_array.each_with_object({}) do |x, hash|
|
52
|
-
|
50
|
+
deep_merge!(hash, parse_include_args(x))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @api private
|
55
|
+
def deep_merge!(src, ext)
|
56
|
+
ext.each do |k, v|
|
57
|
+
if src[k].is_a?(Hash) && v.is_a?(Hash)
|
58
|
+
deep_merge!(src[k], v)
|
59
|
+
else
|
60
|
+
src[k] = v
|
61
|
+
end
|
53
62
|
end
|
54
63
|
end
|
55
64
|
end
|
data/lib/jsonapi/resource.rb
CHANGED
data/lib/jsonapi/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1.
|
4
|
+
version: 0.1.1.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Hosseini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.8'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: activesupport
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '3.0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '3.0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,7 +81,6 @@ files:
|
|
95
81
|
- lib/jsonapi/relationship.rb
|
96
82
|
- lib/jsonapi/relationships.rb
|
97
83
|
- lib/jsonapi/resource.rb
|
98
|
-
- lib/jsonapi/resource/active_record.rb
|
99
84
|
- lib/jsonapi/resource_identifier.rb
|
100
85
|
- lib/jsonapi/version.rb
|
101
86
|
- spec/duplicates_spec.rb
|
@@ -103,7 +88,6 @@ files:
|
|
103
88
|
- spec/include_directive/parser_spec.rb
|
104
89
|
- spec/include_directive_spec.rb
|
105
90
|
- spec/parser_spec.rb
|
106
|
-
- spec/resource/to_activerecord_hash_spec.rb
|
107
91
|
homepage: https://github.com/beauby/jsonapi
|
108
92
|
licenses:
|
109
93
|
- MIT
|
@@ -134,4 +118,3 @@ test_files:
|
|
134
118
|
- spec/include_directive/parser_spec.rb
|
135
119
|
- spec/include_directive_spec.rb
|
136
120
|
- spec/parser_spec.rb
|
137
|
-
- spec/resource/to_activerecord_hash_spec.rb
|
@@ -1,151 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/string/inflections'
|
2
|
-
|
3
|
-
module JSONAPI
|
4
|
-
class Resource
|
5
|
-
# Transform the resource object into a hash ready for ActiveRecord's
|
6
|
-
# new/create/update.
|
7
|
-
#
|
8
|
-
# @example
|
9
|
-
# payload = {
|
10
|
-
# 'data' => {
|
11
|
-
# 'type' => 'articles',
|
12
|
-
# 'id' => '1',
|
13
|
-
# 'attributes' => {
|
14
|
-
# 'title' => 'JSON API paints my bikeshed!',
|
15
|
-
# 'rating' => '5 stars'
|
16
|
-
# },
|
17
|
-
# 'relationships' => {
|
18
|
-
# 'author' => {
|
19
|
-
# 'data' => { 'type' => 'people', 'id' => '9' }
|
20
|
-
# },
|
21
|
-
# 'referree' => {
|
22
|
-
# 'data' => nil
|
23
|
-
# },
|
24
|
-
# 'publishing-journal' => {
|
25
|
-
# 'data' => nil
|
26
|
-
# },
|
27
|
-
# 'comments' => {
|
28
|
-
# 'data' => [
|
29
|
-
# { 'type' => 'comments', 'id' => '5' },
|
30
|
-
# { 'type' => 'comments', 'id' => '12' }
|
31
|
-
# ]
|
32
|
-
# }
|
33
|
-
# }
|
34
|
-
# }
|
35
|
-
# }
|
36
|
-
# document = JSON::API.parse(payload)
|
37
|
-
# options = {
|
38
|
-
# attributes: {
|
39
|
-
# except: [:rating]
|
40
|
-
# },
|
41
|
-
# relationships: {
|
42
|
-
# only: [:author, :'publishing-journal', :comments],
|
43
|
-
# polymorphic: [:author]
|
44
|
-
# },
|
45
|
-
# key_formatter: ->(x) { x.underscore }
|
46
|
-
# }
|
47
|
-
# document.data.to_activerecord_hash(options)
|
48
|
-
# # => {
|
49
|
-
# id: '1',
|
50
|
-
# title: 'JSON API paints my bikeshed!',
|
51
|
-
# author_id: '9',
|
52
|
-
# author_type: 'people',
|
53
|
-
# publishing_journal_id: nil,
|
54
|
-
# comment_ids: ['5', '12']
|
55
|
-
# }
|
56
|
-
#
|
57
|
-
# @param options [Hash]
|
58
|
-
# * :attributes (Hash)
|
59
|
-
# * :only (Array<Symbol,String>)
|
60
|
-
# * :except (Array<Symbol,String>)
|
61
|
-
# * :relationships (Hash)
|
62
|
-
# * :only (Array<Symbol,String>)
|
63
|
-
# * :except (Array<Symbol,String>)
|
64
|
-
# * :polymorphic (Array<Symbol,String>)
|
65
|
-
# * :key_formatter (lambda)
|
66
|
-
# @return [Hash]
|
67
|
-
def to_activerecord_hash(options = {})
|
68
|
-
options[:attributes] ||= {}
|
69
|
-
options[:relationships] ||= {}
|
70
|
-
hash = {}
|
71
|
-
hash[:id] = id unless id.nil?
|
72
|
-
hash.merge!(attributes_for_activerecord_hash(options))
|
73
|
-
hash.merge!(relationships_for_activerecord_hash(options))
|
74
|
-
|
75
|
-
hash
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
def attributes_for_activerecord_hash(options)
|
81
|
-
attributes_hashes =
|
82
|
-
filter_keys(attributes.keys, options[:attributes]).map do |key|
|
83
|
-
attribute_for_activerecord_hash(key, options[:key_formatter])
|
84
|
-
end
|
85
|
-
|
86
|
-
attributes_hashes.reduce({}, :merge)
|
87
|
-
end
|
88
|
-
|
89
|
-
def attribute_for_activerecord_hash(key, key_formatter)
|
90
|
-
{ format_key(key, key_formatter).to_sym => attributes[key] }
|
91
|
-
end
|
92
|
-
|
93
|
-
def relationships_for_activerecord_hash(options)
|
94
|
-
relationship_hashes =
|
95
|
-
filter_keys(relationships.keys, options[:relationships]).map do |key|
|
96
|
-
polymorphic = (options[:relationships][:polymorphic] || [])
|
97
|
-
.include?(key.to_sym)
|
98
|
-
relationship_for_activerecord_hash(key,
|
99
|
-
options[:key_formatter],
|
100
|
-
polymorphic)
|
101
|
-
end
|
102
|
-
|
103
|
-
relationship_hashes.reduce({}, :merge)
|
104
|
-
end
|
105
|
-
|
106
|
-
def relationship_for_activerecord_hash(rel_name,
|
107
|
-
key_formatter,
|
108
|
-
polymorphic)
|
109
|
-
rel = relationships[rel_name]
|
110
|
-
key = format_key(rel_name, key_formatter)
|
111
|
-
|
112
|
-
if rel.collection?
|
113
|
-
to_many_relationship_for_activerecord_hash(key, rel)
|
114
|
-
else
|
115
|
-
to_one_relationship_for_activerecord_hash(key, rel, polymorphic)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def to_many_relationship_for_activerecord_hash(key, rel)
|
120
|
-
{ "#{key.singularize}_ids".to_sym => rel.data.map(&:id) }
|
121
|
-
end
|
122
|
-
|
123
|
-
def to_one_relationship_for_activerecord_hash(key, rel, polymorphic)
|
124
|
-
value = rel.data ? rel.data.id : nil
|
125
|
-
hash = { "#{key}_id".to_sym => value }
|
126
|
-
if polymorphic && !rel.data.nil?
|
127
|
-
hash["#{key}_type".to_sym] = rel.data.type.singularize.capitalize
|
128
|
-
end
|
129
|
-
|
130
|
-
hash
|
131
|
-
end
|
132
|
-
|
133
|
-
def format_key(key, key_formatter)
|
134
|
-
if key_formatter
|
135
|
-
key_formatter.call(key)
|
136
|
-
else
|
137
|
-
key
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def filter_keys(keys, filter)
|
142
|
-
if filter[:only]
|
143
|
-
keys & filter[:only].map(&:to_s)
|
144
|
-
elsif filter[:except]
|
145
|
-
keys - filter[:except].map(&:to_s)
|
146
|
-
else
|
147
|
-
keys
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'jsonapi'
|
2
|
-
|
3
|
-
describe JSONAPI::Resource, '.to_activerecord_hash' do
|
4
|
-
before(:all) do
|
5
|
-
@payload = {
|
6
|
-
'data' => {
|
7
|
-
'type' => 'articles',
|
8
|
-
'id' => '1',
|
9
|
-
'attributes' => {
|
10
|
-
'title' => 'JSON API paints my bikeshed!',
|
11
|
-
'rating' => '5 stars'
|
12
|
-
},
|
13
|
-
'relationships' => {
|
14
|
-
'author' => {
|
15
|
-
'data' => { 'type' => 'people', 'id' => '9' }
|
16
|
-
},
|
17
|
-
'referree' => {
|
18
|
-
'data' => nil
|
19
|
-
},
|
20
|
-
'publishing-journal' => {
|
21
|
-
'data' => nil
|
22
|
-
},
|
23
|
-
'comments' => {
|
24
|
-
'data' => [
|
25
|
-
{ 'type' => 'comments', 'id' => '5' },
|
26
|
-
{ 'type' => 'comments', 'id' => '12' }
|
27
|
-
]
|
28
|
-
}
|
29
|
-
}
|
30
|
-
}
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'works' do
|
35
|
-
document = JSONAPI.parse(@payload)
|
36
|
-
|
37
|
-
options = {
|
38
|
-
attributes: {
|
39
|
-
except: [:rating]
|
40
|
-
},
|
41
|
-
relationships: {
|
42
|
-
only: [:author, :'publishing-journal', :comments],
|
43
|
-
polymorphic: [:author]
|
44
|
-
},
|
45
|
-
key_formatter: ->(x) { x.underscore }
|
46
|
-
}
|
47
|
-
actual = document.data.to_activerecord_hash(options)
|
48
|
-
expected = {
|
49
|
-
id: '1',
|
50
|
-
title: 'JSON API paints my bikeshed!',
|
51
|
-
author_id: '9',
|
52
|
-
author_type: 'Person',
|
53
|
-
publishing_journal_id: nil,
|
54
|
-
comment_ids: ['5', '12']
|
55
|
-
}
|
56
|
-
|
57
|
-
expect(actual).to eq expected
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'whitelists all attributes/relationships by default' do
|
61
|
-
document = JSONAPI.parse(@payload)
|
62
|
-
|
63
|
-
actual = document.data.to_activerecord_hash
|
64
|
-
expected = {
|
65
|
-
id: '1',
|
66
|
-
title: 'JSON API paints my bikeshed!',
|
67
|
-
rating: '5 stars',
|
68
|
-
author_id: '9',
|
69
|
-
referree_id: nil,
|
70
|
-
:'publishing-journal_id' => nil,
|
71
|
-
comment_ids: ['5', '12']
|
72
|
-
}
|
73
|
-
|
74
|
-
expect(actual).to eq expected
|
75
|
-
end
|
76
|
-
end
|