json_api_client 1.0.0.beta → 1.0.0.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/lib/json_api_client/connection.rb +2 -1
- data/lib/json_api_client/error_collector.rb +65 -14
- data/lib/json_api_client/helpers/associable.rb +1 -1
- data/lib/json_api_client/helpers/initializable.rb +1 -1
- data/lib/json_api_client/helpers/linkable.rb +1 -27
- data/lib/json_api_client/helpers/paginatable.rb +2 -1
- data/lib/json_api_client/helpers/relatable.rb +45 -0
- data/lib/json_api_client/helpers/requestable.rb +2 -2
- data/lib/json_api_client/helpers/serializable.rb +16 -5
- data/lib/json_api_client/helpers.rb +1 -0
- data/lib/json_api_client/implementation.rb +12 -0
- data/lib/json_api_client/included_data.rb +49 -0
- data/lib/json_api_client/linking/links.rb +1 -8
- data/lib/json_api_client/linking/top_level_links.rb +1 -1
- data/lib/json_api_client/linking.rb +0 -1
- data/lib/json_api_client/paginating/paginator.rb +4 -3
- data/lib/json_api_client/parsers/parser.rb +53 -7
- data/lib/json_api_client/query/builder.rb +13 -4
- data/lib/json_api_client/query/requestor.rb +3 -3
- data/lib/json_api_client/relationships/relations.rb +29 -0
- data/lib/json_api_client/relationships/top_level_relations.rb +30 -0
- data/lib/json_api_client/relationships.rb +6 -0
- data/lib/json_api_client/resource.rb +3 -6
- data/lib/json_api_client/result_set.rb +5 -2
- data/lib/json_api_client/version.rb +1 -1
- data/lib/json_api_client.rb +2 -0
- metadata +8 -3
- data/lib/json_api_client/linking/included_data.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 738f41ec73db3cf6cdf208abb4ad48ea7fc50e39
|
4
|
+
data.tar.gz: a0b6dfce9e509e9d7ac206ba742ce3b52e41a04e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d20ef7885deb0589bbb6d6d7fa89d40ef7dbf192e1461ba006f4124c0986a581ce0da11d1bf5d9ce308610ef142effcc11ceb7aa4a91f78752db9f511357837e
|
7
|
+
data.tar.gz: 2dd89bd5ea1b889f71a1b62826f087ebb30078a38f20218483fdf119928a3e0f724db2f10fb2dfcef58dba7ab3f48b108d7c9ade2133f469aed8dbf4c47dbaaf
|
@@ -5,12 +5,13 @@ module JsonApiClient
|
|
5
5
|
|
6
6
|
def initialize(options = {})
|
7
7
|
site = options.fetch(:site)
|
8
|
+
adapter_options = Array(options.fetch(:adapter, Faraday.default_adapter))
|
8
9
|
@faraday = Faraday.new(site) do |builder|
|
9
10
|
builder.request :json
|
10
11
|
builder.use Middleware::JsonRequest
|
11
12
|
builder.use Middleware::Status
|
12
13
|
builder.use Middleware::ParseJson
|
13
|
-
builder.adapter
|
14
|
+
builder.adapter *adapter_options
|
14
15
|
end
|
15
16
|
yield(self) if block_given?
|
16
17
|
end
|
@@ -1,28 +1,79 @@
|
|
1
1
|
module JsonApiClient
|
2
|
-
class ErrorCollector
|
2
|
+
class ErrorCollector < Array
|
3
3
|
class Error
|
4
|
-
|
4
|
+
delegate :[], to: :attrs
|
5
5
|
|
6
6
|
def initialize(attrs = {})
|
7
|
-
attrs = {
|
8
|
-
title: attrs
|
9
|
-
} if attrs.is_a?(String)
|
10
|
-
self.attributes = attrs
|
7
|
+
@attrs = (attrs || {}).with_indifferent_access
|
11
8
|
end
|
12
|
-
end
|
13
9
|
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
def id
|
11
|
+
attrs[:id]
|
12
|
+
end
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
def about
|
15
|
+
attrs.fetch(:links, {})[:about]
|
16
|
+
end
|
17
|
+
|
18
|
+
def status
|
19
|
+
attrs[:status]
|
20
|
+
end
|
21
|
+
|
22
|
+
def code
|
23
|
+
attrs[:code]
|
21
24
|
end
|
25
|
+
|
26
|
+
def title
|
27
|
+
attrs[:title]
|
28
|
+
end
|
29
|
+
|
30
|
+
def detail
|
31
|
+
attrs[:detail]
|
32
|
+
end
|
33
|
+
|
34
|
+
def source_parameter
|
35
|
+
source.fetch(:parameter) do
|
36
|
+
source[:pointer] ?
|
37
|
+
source[:pointer].split("/").last :
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def source_pointer
|
43
|
+
source.fetch(:pointer) do
|
44
|
+
source[:parameter] ?
|
45
|
+
"/data/attributes/#{source[:parameter]}" :
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def source
|
51
|
+
attrs.fetch(:source, {})
|
52
|
+
end
|
53
|
+
|
54
|
+
def meta
|
55
|
+
MetaData.new(attrs.fetch(:meta, {}))
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
attr_reader :attrs
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize(error_data)
|
64
|
+
super(error_data.map do |data|
|
65
|
+
Error.new(data)
|
66
|
+
end)
|
22
67
|
end
|
23
68
|
|
24
69
|
def full_messages
|
25
|
-
|
70
|
+
map(&:title)
|
71
|
+
end
|
72
|
+
|
73
|
+
def [](source)
|
74
|
+
map do |error|
|
75
|
+
error.source_parameter == source
|
76
|
+
end
|
26
77
|
end
|
27
78
|
|
28
79
|
end
|
@@ -10,9 +10,6 @@ module JsonApiClient
|
|
10
10
|
# the links for this resource
|
11
11
|
attr_accessor :links
|
12
12
|
|
13
|
-
# reference to all of the preloaded data
|
14
|
-
attr_accessor :linked_data
|
15
|
-
|
16
13
|
initializer do |obj, params|
|
17
14
|
links = params && params.delete("links")
|
18
15
|
links ||= {}
|
@@ -20,29 +17,6 @@ module JsonApiClient
|
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
23
|
-
def as_link
|
24
|
-
{
|
25
|
-
:type => self.class.table_name,
|
26
|
-
primary_key => self[primary_key]
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
def attributes
|
31
|
-
super.tap do |attrs|
|
32
|
-
attrs.merge!(links: links.attributes) if links.present?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def method_missing(method, *args)
|
37
|
-
return super unless links && links.has_attribute?(method)
|
38
|
-
linked_data.data_for(method, links[method])
|
39
|
-
end
|
40
|
-
|
41
|
-
def respond_to_missing?(symbol, include_all = false)
|
42
|
-
return true if links && links.has_attribute?(symbol)
|
43
|
-
super
|
44
|
-
end
|
45
|
-
|
46
20
|
end
|
47
21
|
end
|
48
|
-
end
|
22
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module JsonApiClient
|
2
|
+
module Helpers
|
3
|
+
module Relatable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :relationship_linker
|
8
|
+
self.relationship_linker = Relationships::Relations
|
9
|
+
|
10
|
+
# the relationships for this resource
|
11
|
+
attr_accessor :relationships
|
12
|
+
|
13
|
+
initializer do |obj, params|
|
14
|
+
relationships = params && params.delete("relationships")
|
15
|
+
relationships ||= {}
|
16
|
+
obj.relationships = obj.relationship_linker.new(relationships)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def as_relation
|
21
|
+
{
|
22
|
+
:type => self.class.table_name,
|
23
|
+
primary_key => self[primary_key]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def attributes
|
28
|
+
super.tap do |attrs|
|
29
|
+
attrs.merge!(relationships: relationships.attributes) if relationships.present?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(method, *args)
|
34
|
+
return super unless relationships and relationships.has_attribute?(method) and result_set.included
|
35
|
+
result_set.included.data_for(method, relationships[method])
|
36
|
+
end
|
37
|
+
|
38
|
+
def respond_to_missing?(symbol, include_all = false)
|
39
|
+
return true if relationships && relationships.has_attribute?(symbol)
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -32,8 +32,8 @@ module JsonApiClient
|
|
32
32
|
self.class.requestor.create(self)
|
33
33
|
end
|
34
34
|
|
35
|
+
self.errors = last_result_set.errors
|
35
36
|
if last_result_set.has_errors?
|
36
|
-
self.errors = last_result_set.errors
|
37
37
|
false
|
38
38
|
else
|
39
39
|
self.errors.clear if self.errors
|
@@ -57,4 +57,4 @@ module JsonApiClient
|
|
57
57
|
|
58
58
|
end
|
59
59
|
end
|
60
|
-
end
|
60
|
+
end
|
@@ -1,13 +1,24 @@
|
|
1
1
|
module JsonApiClient
|
2
2
|
module Helpers
|
3
3
|
module Serializable
|
4
|
-
|
5
|
-
|
4
|
+
RESERVED = ['id', 'type', 'links', 'meta', 'relationships']
|
5
|
+
|
6
|
+
# def as_json(options=nil)
|
7
|
+
# attributes.slice(*RESERVED).tap do |h|
|
8
|
+
# h['attributes'] = serialized_attributes
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
|
12
|
+
def data
|
13
|
+
attributes.slice(*RESERVED).tap do |h|
|
14
|
+
h['attributes'] = serialized_attributes
|
15
|
+
end
|
6
16
|
end
|
7
17
|
|
8
|
-
def
|
9
|
-
|
18
|
+
def serialized_attributes
|
19
|
+
attributes.except(*RESERVED)
|
10
20
|
end
|
21
|
+
|
11
22
|
end
|
12
23
|
end
|
13
|
-
end
|
24
|
+
end
|
@@ -6,6 +6,7 @@ module JsonApiClient
|
|
6
6
|
autoload :DynamicAttributes, 'json_api_client/helpers/dynamic_attributes'
|
7
7
|
autoload :Initializable, 'json_api_client/helpers/initializable'
|
8
8
|
autoload :Linkable, 'json_api_client/helpers/linkable'
|
9
|
+
autoload :Relatable, 'json_api_client/helpers/relatable'
|
9
10
|
autoload :Paginatable, 'json_api_client/helpers/paginatable'
|
10
11
|
autoload :Parsable, 'json_api_client/helpers/parsable'
|
11
12
|
autoload :Queryable, 'json_api_client/helpers/queryable'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module JsonApiClient
|
2
|
+
class Implementation
|
3
|
+
attr_reader :version, :meta
|
4
|
+
|
5
|
+
def initialize(data)
|
6
|
+
# If the version member is not present, clients should assume the server implements at least version 1.0 of the specification.
|
7
|
+
@version = data.fetch("version", "1.0")
|
8
|
+
|
9
|
+
@meta = MetaData.new(data.fetch("meta", {}))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module JsonApiClient
|
2
|
+
class IncludedData
|
3
|
+
attr_reader :data
|
4
|
+
|
5
|
+
def initialize(result_set, data)
|
6
|
+
record_class = result_set.record_class
|
7
|
+
grouped_data = data.group_by{|datum| datum["type"]}
|
8
|
+
@data = grouped_data.inject({}) do |h, (type, records)|
|
9
|
+
klass = Utils.compute_type(record_class, type.singularize.classify)
|
10
|
+
h[type] = records.map do |datum|
|
11
|
+
params = klass.parser.parameters_from_resource(datum)
|
12
|
+
resource = klass.new(params)
|
13
|
+
resource.result_set = result_set
|
14
|
+
resource
|
15
|
+
end.index_by(&:id)
|
16
|
+
h
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def data_for(method_name, definition)
|
21
|
+
# If data is defined, pull the record from the included data
|
22
|
+
if data = definition["data"]
|
23
|
+
if data.is_a?(Array)
|
24
|
+
# has_many link
|
25
|
+
data.map do |link_def|
|
26
|
+
record_for(link_def)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
# has_one link
|
30
|
+
record_for(data)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
# TODO: if "related" URI is defined, fetch the delated object and stuff it in data
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_link?(name)
|
39
|
+
data.has_key?(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# should return a resource record of some type for this linked document
|
45
|
+
def record_for(link_def)
|
46
|
+
data[link_def["type"]][link_def["id"]]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -14,14 +14,7 @@ module JsonApiClient
|
|
14
14
|
protected
|
15
15
|
|
16
16
|
def set_attribute(name, value)
|
17
|
-
attributes[name] =
|
18
|
-
when JsonApiClient::Resource
|
19
|
-
{linkage: value.as_link}
|
20
|
-
when Array
|
21
|
-
{linkage: value.map(&:as_link)}
|
22
|
-
else
|
23
|
-
value
|
24
|
-
end
|
17
|
+
attributes[name] = value
|
25
18
|
end
|
26
19
|
|
27
20
|
end
|
@@ -2,10 +2,10 @@ module JsonApiClient
|
|
2
2
|
module Paginating
|
3
3
|
class Paginator
|
4
4
|
attr_reader :params, :result_set, :links
|
5
|
-
def initialize(result_set,
|
5
|
+
def initialize(result_set, data)
|
6
6
|
@params = params_for_uri(result_set.uri)
|
7
7
|
@result_set = result_set
|
8
|
-
@links = links
|
8
|
+
@links = data['links']
|
9
9
|
end
|
10
10
|
|
11
11
|
def next
|
@@ -39,6 +39,7 @@ module JsonApiClient
|
|
39
39
|
def total_entries
|
40
40
|
per_page * total_pages
|
41
41
|
end
|
42
|
+
alias_method :total_count, :total_entries
|
42
43
|
|
43
44
|
def offset
|
44
45
|
per_page * (current_page - 1)
|
@@ -77,4 +78,4 @@ module JsonApiClient
|
|
77
78
|
end
|
78
79
|
end
|
79
80
|
end
|
80
|
-
end
|
81
|
+
end
|
@@ -7,24 +7,69 @@ module JsonApiClient
|
|
7
7
|
ResultSet.new.tap do |result_set|
|
8
8
|
result_set.record_class = klass
|
9
9
|
result_set.uri = response.env[:url]
|
10
|
+
handle_json_api(result_set, data)
|
10
11
|
handle_data(result_set, data)
|
11
12
|
handle_errors(result_set, data)
|
12
13
|
handle_meta(result_set, data)
|
13
14
|
handle_links(result_set, data)
|
15
|
+
handle_relationships(result_set, data)
|
14
16
|
handle_pagination(result_set, data)
|
15
17
|
handle_included(result_set, data)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
#
|
22
|
+
# Given a resource hash, returns a Resource.new friendly hash
|
23
|
+
# which flattens the attributes in w/ id and type.
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
#
|
27
|
+
# Given:
|
28
|
+
# {
|
29
|
+
# id: 1.
|
30
|
+
# type: 'person',
|
31
|
+
# attributes: {
|
32
|
+
# first_name: 'Jeff',
|
33
|
+
# last_name: 'Ching'
|
34
|
+
# },
|
35
|
+
# links: {...},
|
36
|
+
# relationships: {...}
|
37
|
+
# }
|
38
|
+
#
|
39
|
+
# Returns:
|
40
|
+
# {
|
41
|
+
# id: 1,
|
42
|
+
# type: 'person',
|
43
|
+
# first_name: 'Jeff',
|
44
|
+
# last_name: 'Ching'
|
45
|
+
# links: {...},
|
46
|
+
# relationships: {...}
|
47
|
+
# }
|
48
|
+
#
|
49
|
+
#
|
50
|
+
def parameters_from_resource(params)
|
51
|
+
attrs = params.slice('id', 'links', 'meta', 'type', 'relationships')
|
52
|
+
attrs.merge(params.fetch('attributes', {}))
|
53
|
+
end
|
54
|
+
|
19
55
|
private
|
20
56
|
|
57
|
+
def handle_json_api(result_set, data)
|
58
|
+
result_set.implementation = Implementation.new(data.fetch("jsonapi", {}))
|
59
|
+
end
|
60
|
+
|
21
61
|
def handle_data(result_set, data)
|
22
62
|
# all data lives under the "data" attribute
|
23
63
|
results = data.fetch("data", [])
|
24
64
|
|
25
65
|
# we will treat everything as an Array
|
26
66
|
results = [results] unless results.is_a?(Array)
|
27
|
-
|
67
|
+
resources = results.map do |res|
|
68
|
+
resource = result_set.record_class.load(parameters_from_resource(res))
|
69
|
+
resource.result_set = result_set
|
70
|
+
resource
|
71
|
+
end
|
72
|
+
result_set.concat(resources)
|
28
73
|
end
|
29
74
|
|
30
75
|
def handle_errors(result_set, data)
|
@@ -39,17 +84,18 @@ module JsonApiClient
|
|
39
84
|
result_set.links = Linking::TopLevelLinks.new(result_set.record_class, data.fetch("links", {}))
|
40
85
|
end
|
41
86
|
|
87
|
+
def handle_relationships(result_set, data)
|
88
|
+
result_set.relationships = Relationships::TopLevelRelations.new(result_set.record_class, data.fetch("relationships", {}))
|
89
|
+
end
|
90
|
+
|
42
91
|
def handle_pagination(result_set, data)
|
43
|
-
result_set.pages = result_set.record_class.paginator.new(result_set, data
|
92
|
+
result_set.pages = result_set.record_class.paginator.new(result_set, data)
|
44
93
|
end
|
45
94
|
|
46
95
|
def handle_included(result_set, data)
|
47
|
-
included =
|
48
|
-
result_set.each do |res|
|
49
|
-
res.linked_data = included
|
50
|
-
end
|
96
|
+
result_set.included = IncludedData.new(result_set, data.fetch("included", []))
|
51
97
|
end
|
52
98
|
end
|
53
99
|
end
|
54
100
|
end
|
55
|
-
end
|
101
|
+
end
|
@@ -34,12 +34,19 @@ module JsonApiClient
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def paginate(conditions = {})
|
37
|
-
|
38
|
-
|
37
|
+
scope = self
|
38
|
+
scope = scope.page(conditions[:page]) if conditions[:page]
|
39
|
+
scope = scope.per(conditions[:per_page]) if conditions[:per_page]
|
40
|
+
scope
|
39
41
|
end
|
40
42
|
|
41
43
|
def page(number)
|
42
|
-
@pagination_params[:
|
44
|
+
@pagination_params[:number] = number
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def per(size)
|
49
|
+
@pagination_params[:size] = size
|
43
50
|
self
|
44
51
|
end
|
45
52
|
|
@@ -70,7 +77,9 @@ module JsonApiClient
|
|
70
77
|
|
71
78
|
private
|
72
79
|
|
73
|
-
|
80
|
+
def pagination_params
|
81
|
+
@pagination_params.empty? ? {} : {page: @pagination_params}
|
82
|
+
end
|
74
83
|
|
75
84
|
def includes_params
|
76
85
|
@includes.empty? ? {} : {include: @includes.join(",")}
|
@@ -10,13 +10,13 @@ module JsonApiClient
|
|
10
10
|
# expects a record
|
11
11
|
def create(record)
|
12
12
|
request(:post, klass.path(record.attributes), {
|
13
|
-
data: record.
|
13
|
+
data: record.data
|
14
14
|
})
|
15
15
|
end
|
16
16
|
|
17
17
|
def update(record)
|
18
18
|
request(:patch, resource_path(record.attributes), {
|
19
|
-
data: record.
|
19
|
+
data: record.data
|
20
20
|
})
|
21
21
|
end
|
22
22
|
|
@@ -74,4 +74,4 @@ module JsonApiClient
|
|
74
74
|
|
75
75
|
end
|
76
76
|
end
|
77
|
-
end
|
77
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module JsonApiClient
|
2
|
+
module Relationships
|
3
|
+
class Relations
|
4
|
+
include Helpers::DynamicAttributes
|
5
|
+
|
6
|
+
def initialize(relations)
|
7
|
+
self.attributes = relations
|
8
|
+
end
|
9
|
+
|
10
|
+
def present?
|
11
|
+
attributes.present?
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def set_attribute(name, value)
|
17
|
+
attributes[name] = case value
|
18
|
+
when JsonApiClient::Resource
|
19
|
+
{data: value.as_relation}
|
20
|
+
when Array
|
21
|
+
{data: value.map(&:as_relation)}
|
22
|
+
else
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module JsonApiClient
|
2
|
+
module Relationships
|
3
|
+
class TopLevelRelations
|
4
|
+
|
5
|
+
attr_reader :relations, :record_class
|
6
|
+
|
7
|
+
def initialize(record_class, relations)
|
8
|
+
@relations = relations
|
9
|
+
@record_class = record_class
|
10
|
+
end
|
11
|
+
|
12
|
+
def respond_to_missing?(method, include_private = false)
|
13
|
+
relations.has_key?(method.to_s) || super
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(method, *args)
|
17
|
+
if respond_to_missing?(method)
|
18
|
+
fetch_relation(method)
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch_relation(relation_name)
|
25
|
+
link_definition = relations.fetch(relation_name.to_s)
|
26
|
+
record_class.requestor.linked(link_definition)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,13 +1,9 @@
|
|
1
1
|
require 'forwardable'
|
2
|
-
require 'active_support/
|
3
|
-
require 'active_support/inflector'
|
4
|
-
require 'active_support/core_ext/hash'
|
5
|
-
require 'active_support/core_ext/module'
|
6
|
-
require 'active_support/core_ext/class/attribute'
|
7
|
-
require 'active_support/core_ext/enumerable'
|
2
|
+
require 'active_support/all'
|
8
3
|
|
9
4
|
module JsonApiClient
|
10
5
|
class Resource
|
6
|
+
attr_accessor :result_set
|
11
7
|
class_attribute :site, :primary_key
|
12
8
|
self.primary_key = :id
|
13
9
|
|
@@ -33,6 +29,7 @@ module JsonApiClient
|
|
33
29
|
include Helpers::Queryable
|
34
30
|
include Helpers::Serializable
|
35
31
|
include Helpers::Linkable
|
32
|
+
include Helpers::Relatable
|
36
33
|
include Helpers::CustomEndpoints
|
37
34
|
include Helpers::Schemable
|
38
35
|
include Helpers::Paginatable
|
@@ -9,10 +9,13 @@ module JsonApiClient
|
|
9
9
|
:meta,
|
10
10
|
:pages,
|
11
11
|
:uri,
|
12
|
-
:links
|
12
|
+
:links,
|
13
|
+
:implementation,
|
14
|
+
:relationships,
|
15
|
+
:included
|
13
16
|
|
14
17
|
# pagination methods are handled by the paginator
|
15
|
-
def_delegators :pages, :total_pages, :total_entries, :offset, :per_page, :current_page, :limit_value, :next_page, :previous_page, :out_of_bounds?
|
18
|
+
def_delegators :pages, :total_pages, :total_entries, :total_count, :offset, :per_page, :current_page, :limit_value, :next_page, :previous_page, :out_of_bounds?
|
16
19
|
|
17
20
|
def has_errors?
|
18
21
|
errors.present?
|
data/lib/json_api_client.rb
CHANGED
@@ -10,8 +10,10 @@ module JsonApiClient
|
|
10
10
|
autoload :Errors, 'json_api_client/errors'
|
11
11
|
autoload :ErrorCollector, 'json_api_client/error_collector'
|
12
12
|
autoload :Helpers, 'json_api_client/helpers'
|
13
|
+
autoload :Implementation, 'json_api_client/implementation'
|
13
14
|
autoload :IncludedData, 'json_api_client/included_data'
|
14
15
|
autoload :Linking, 'json_api_client/linking'
|
16
|
+
autoload :Relationships, 'json_api_client/relationships'
|
15
17
|
autoload :LinkDefinition, 'json_api_client/link_definition'
|
16
18
|
autoload :MetaData, 'json_api_client/meta_data'
|
17
19
|
autoload :Middleware, 'json_api_client/middleware'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_api_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Ching
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -122,11 +122,13 @@ files:
|
|
122
122
|
- lib/json_api_client/helpers/paginatable.rb
|
123
123
|
- lib/json_api_client/helpers/parsable.rb
|
124
124
|
- lib/json_api_client/helpers/queryable.rb
|
125
|
+
- lib/json_api_client/helpers/relatable.rb
|
125
126
|
- lib/json_api_client/helpers/requestable.rb
|
126
127
|
- lib/json_api_client/helpers/schemable.rb
|
127
128
|
- lib/json_api_client/helpers/serializable.rb
|
129
|
+
- lib/json_api_client/implementation.rb
|
130
|
+
- lib/json_api_client/included_data.rb
|
128
131
|
- lib/json_api_client/linking.rb
|
129
|
-
- lib/json_api_client/linking/included_data.rb
|
130
132
|
- lib/json_api_client/linking/links.rb
|
131
133
|
- lib/json_api_client/linking/top_level_links.rb
|
132
134
|
- lib/json_api_client/meta_data.rb
|
@@ -141,6 +143,9 @@ files:
|
|
141
143
|
- lib/json_api_client/query.rb
|
142
144
|
- lib/json_api_client/query/builder.rb
|
143
145
|
- lib/json_api_client/query/requestor.rb
|
146
|
+
- lib/json_api_client/relationships.rb
|
147
|
+
- lib/json_api_client/relationships/relations.rb
|
148
|
+
- lib/json_api_client/relationships/top_level_relations.rb
|
144
149
|
- lib/json_api_client/resource.rb
|
145
150
|
- lib/json_api_client/result_set.rb
|
146
151
|
- lib/json_api_client/schema.rb
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module JsonApiClient
|
2
|
-
module Linking
|
3
|
-
class IncludedData
|
4
|
-
attr_reader :data
|
5
|
-
|
6
|
-
def initialize(record_class, data)
|
7
|
-
grouped_data = data.group_by{|datum| datum["type"]}
|
8
|
-
@data = grouped_data.inject({}) do |h, (type, records)|
|
9
|
-
klass = Utils.compute_type(record_class, type.singularize.classify)
|
10
|
-
h[type] = records.map{|datum| klass.new(datum)}.index_by(&:id)
|
11
|
-
h
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def data_for(method_name, definition)
|
16
|
-
linkage = definition["linkage"]
|
17
|
-
if linkage.is_a?(Array)
|
18
|
-
# has_many link
|
19
|
-
linkage.map do |link_def|
|
20
|
-
record_for(link_def)
|
21
|
-
end
|
22
|
-
else
|
23
|
-
# has_one link
|
24
|
-
record_for(linkage)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def has_link?(name)
|
29
|
-
data.has_key?(name)
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
# should return a resource record of some type for this linked document
|
35
|
-
def record_for(link_def)
|
36
|
-
data[link_def["type"]][link_def["id"]]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|