jsonapi-consumer 0.1.1 → 1.0.0
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 +5 -5
- data/.circleci/config.yml +27 -0
- data/.gitignore +1 -0
- data/Gemfile +6 -4
- data/README.md +9 -38
- data/Rakefile +17 -6
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/jsonapi-consumer.gemspec +10 -11
- data/lib/jsonapi/consumer/associations/base_association.rb +26 -0
- data/lib/jsonapi/consumer/associations/belongs_to.rb +30 -0
- data/lib/jsonapi/consumer/associations/has_many.rb +26 -0
- data/lib/jsonapi/consumer/associations/has_one.rb +19 -0
- data/lib/jsonapi/consumer/connection.rb +36 -0
- data/lib/jsonapi/consumer/error_collector.rb +91 -0
- data/lib/jsonapi/consumer/errors.rb +34 -76
- data/lib/jsonapi/consumer/formatter.rb +145 -0
- data/lib/jsonapi/consumer/helpers/callbacks.rb +27 -0
- data/lib/jsonapi/consumer/helpers/dirty.rb +71 -0
- data/lib/jsonapi/consumer/helpers/dynamic_attributes.rb +83 -0
- data/lib/jsonapi/consumer/helpers/uri.rb +9 -0
- data/lib/jsonapi/consumer/implementation.rb +12 -0
- data/lib/jsonapi/consumer/included_data.rb +49 -0
- data/lib/jsonapi/consumer/linking/links.rb +22 -0
- data/lib/jsonapi/consumer/linking/top_level_links.rb +39 -0
- data/lib/jsonapi/consumer/meta_data.rb +19 -0
- data/lib/jsonapi/consumer/middleware/json_request.rb +26 -0
- data/lib/jsonapi/consumer/middleware/parse_json.rb +22 -23
- data/lib/jsonapi/consumer/middleware/status.rb +41 -0
- data/lib/jsonapi/consumer/paginating/paginator.rb +89 -0
- data/lib/jsonapi/consumer/parsers/parser.rb +113 -0
- data/lib/jsonapi/consumer/query/builder.rb +212 -0
- data/lib/jsonapi/consumer/query/requestor.rb +67 -0
- data/lib/jsonapi/consumer/relationships/relations.rb +56 -0
- data/lib/jsonapi/consumer/relationships/top_level_relations.rb +30 -0
- data/lib/jsonapi/consumer/resource.rb +514 -54
- data/lib/jsonapi/consumer/result_set.rb +25 -0
- data/lib/jsonapi/consumer/schema.rb +153 -0
- data/lib/jsonapi/consumer/utils.rb +28 -0
- data/lib/jsonapi/consumer/version.rb +1 -1
- data/lib/jsonapi/consumer.rb +59 -34
- metadata +51 -111
- data/.rspec +0 -2
- data/CHANGELOG.md +0 -36
- data/lib/jsonapi/consumer/middleware/raise_error.rb +0 -21
- data/lib/jsonapi/consumer/middleware/request_headers.rb +0 -20
- data/lib/jsonapi/consumer/middleware/request_timeout.rb +0 -9
- data/lib/jsonapi/consumer/middleware.rb +0 -5
- data/lib/jsonapi/consumer/parser.rb +0 -75
- data/lib/jsonapi/consumer/query/base.rb +0 -34
- data/lib/jsonapi/consumer/query/create.rb +0 -9
- data/lib/jsonapi/consumer/query/delete.rb +0 -10
- data/lib/jsonapi/consumer/query/find.rb +0 -16
- data/lib/jsonapi/consumer/query/new.rb +0 -15
- data/lib/jsonapi/consumer/query/update.rb +0 -11
- data/lib/jsonapi/consumer/query.rb +0 -5
- data/lib/jsonapi/consumer/resource/association_concern.rb +0 -203
- data/lib/jsonapi/consumer/resource/attributes_concern.rb +0 -70
- data/lib/jsonapi/consumer/resource/connection_concern.rb +0 -99
- data/lib/jsonapi/consumer/resource/finders_concern.rb +0 -28
- data/lib/jsonapi/consumer/resource/object_build_concern.rb +0 -28
- data/lib/jsonapi/consumer/resource/serializer_concern.rb +0 -63
- data/spec/fixtures/.gitkeep +0 -0
- data/spec/fixtures/resources.rb +0 -45
- data/spec/fixtures/responses.rb +0 -64
- data/spec/jsonapi/consumer/associations_spec.rb +0 -166
- data/spec/jsonapi/consumer/attributes_spec.rb +0 -27
- data/spec/jsonapi/consumer/connection_spec.rb +0 -147
- data/spec/jsonapi/consumer/error_handling_spec.rb +0 -37
- data/spec/jsonapi/consumer/object_build_spec.rb +0 -20
- data/spec/jsonapi/consumer/parser_spec.rb +0 -39
- data/spec/jsonapi/consumer/resource_spec.rb +0 -62
- data/spec/jsonapi/consumer/serializer_spec.rb +0 -41
- data/spec/spec_helper.rb +0 -97
- data/spec/support/.gitkeep +0 -0
- data/spec/support/load_fixtures.rb +0 -4
@@ -1,75 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer
|
2
|
-
class Parser
|
3
|
-
attr_reader :response, :klass
|
4
|
-
|
5
|
-
def initialize(klass, response)
|
6
|
-
@klass = klass
|
7
|
-
@response = response
|
8
|
-
end
|
9
|
-
|
10
|
-
def attributes(item)
|
11
|
-
item.except(:links)
|
12
|
-
end
|
13
|
-
|
14
|
-
def associations(item)
|
15
|
-
associations = {}
|
16
|
-
item.fetch(:links, {}).each do |assoc_name, ids|
|
17
|
-
associations[assoc_name] = if ids.is_a?(Array)
|
18
|
-
ids.collect {|id| find_linked(assoc_name, id) }
|
19
|
-
else
|
20
|
-
find_linked(assoc_name, ids)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
associations
|
24
|
-
end
|
25
|
-
|
26
|
-
def fetch_resource
|
27
|
-
link_body = _body.fetch(:links, {})
|
28
|
-
|
29
|
-
links = {}
|
30
|
-
|
31
|
-
link_body.each do |key, url|
|
32
|
-
links[key.split('.').last] = url
|
33
|
-
end
|
34
|
-
|
35
|
-
links
|
36
|
-
end
|
37
|
-
|
38
|
-
def fetch_linked(assoc_name, id)
|
39
|
-
klass._association_class_name(assoc_name).find(id)
|
40
|
-
end
|
41
|
-
|
42
|
-
def find_linked(assoc_name, id)
|
43
|
-
if found = linked.fetch(assoc_name.pluralize, []).detect {|h| h.fetch(:id) == id }
|
44
|
-
klass._association_class_name(assoc_name).new(found)
|
45
|
-
else
|
46
|
-
fetch_linked(assoc_name, id)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def linked
|
51
|
-
linked_body = _body.fetch(:linked, {})
|
52
|
-
|
53
|
-
linked = {}
|
54
|
-
linked_body.each do |key, obj_attrs|
|
55
|
-
linked[key] = obj_attrs
|
56
|
-
end
|
57
|
-
linked
|
58
|
-
end
|
59
|
-
|
60
|
-
def build
|
61
|
-
_body.fetch(klass.json_key, []).collect do |attrs|
|
62
|
-
attrs_hash = attributes(attrs).merge(associations(attrs))
|
63
|
-
klass.new(attrs_hash)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def _body
|
68
|
-
response.body.with_indifferent_access
|
69
|
-
end
|
70
|
-
|
71
|
-
def _status
|
72
|
-
reponse.status
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Query
|
2
|
-
class Base
|
3
|
-
class << self
|
4
|
-
attr_accessor :request_method
|
5
|
-
end
|
6
|
-
attr_reader :klass, :headers, :path, :params
|
7
|
-
|
8
|
-
def initialize(klass, payload)
|
9
|
-
@klass = klass
|
10
|
-
build_params(payload) if payload.is_a?(Hash) && payload.keys != [klass.primary_key]
|
11
|
-
|
12
|
-
@path = begin
|
13
|
-
if payload.is_a?(Hash) && payload.has_key?(klass.primary_key)
|
14
|
-
[klass.path, payload.delete(klass.primary_key)].join('/')
|
15
|
-
else
|
16
|
-
klass.path
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def build_params(args)
|
22
|
-
@params = args.dup
|
23
|
-
end
|
24
|
-
|
25
|
-
def request_method
|
26
|
-
self.class.request_method
|
27
|
-
end
|
28
|
-
|
29
|
-
def inspect
|
30
|
-
"#{self.class.name}: method: #{request_method}; path: #{path}; params: #{params}, headers: #{headers}"
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Query
|
2
|
-
class Find < Base
|
3
|
-
self.request_method = :get
|
4
|
-
|
5
|
-
def build_params(args)
|
6
|
-
@params = case args
|
7
|
-
when Hash
|
8
|
-
args
|
9
|
-
when Array
|
10
|
-
{klass.primary_key.to_s.pluralize.to_sym => args.join(",")}
|
11
|
-
else
|
12
|
-
{klass.primary_key => args}
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Query
|
2
|
-
class New < Base
|
3
|
-
self.request_method = :get
|
4
|
-
|
5
|
-
def initialize(klass, payload)
|
6
|
-
super
|
7
|
-
@path = [klass.path, 'new'].join('/')
|
8
|
-
end
|
9
|
-
|
10
|
-
# def build_params(args)
|
11
|
-
# @params = {klass.json_key => args}
|
12
|
-
# end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
@@ -1,203 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Resource
|
2
|
-
class MisconfiguredAssociation < StandardError; end
|
3
|
-
|
4
|
-
module AssociationConcern
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
module ClassMethods
|
8
|
-
attr_writer :_associations
|
9
|
-
|
10
|
-
# Defines a has many relationship.
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
# class User
|
14
|
-
# include JSONAPI::Consumer::Resource
|
15
|
-
# has_many :articles, class_name: 'Article'
|
16
|
-
# end
|
17
|
-
def has_many(*attrs)
|
18
|
-
associate(:has_many, attrs)
|
19
|
-
end
|
20
|
-
|
21
|
-
# @todo belongs to is not supported yet.
|
22
|
-
#
|
23
|
-
def belongs_to(*attrs)
|
24
|
-
associate(:belongs_to, attrs)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Defines a single relationship.
|
28
|
-
#
|
29
|
-
# @example
|
30
|
-
# class Article
|
31
|
-
# include JSONAPI::Consumer::Resource
|
32
|
-
# has_one :user, class_name: 'User'
|
33
|
-
# end
|
34
|
-
def has_one(*attrs)
|
35
|
-
associate(:has_one, attrs)
|
36
|
-
end
|
37
|
-
|
38
|
-
# :nodoc:
|
39
|
-
def _associations
|
40
|
-
@_associations ||= {}
|
41
|
-
end
|
42
|
-
|
43
|
-
# :nodoc:
|
44
|
-
def _association_for(name)
|
45
|
-
_associations[name.to_sym]
|
46
|
-
end
|
47
|
-
|
48
|
-
# :nodoc:
|
49
|
-
def _association_type(name)
|
50
|
-
_association_for(name).fetch(:type)
|
51
|
-
end
|
52
|
-
|
53
|
-
# :nodoc:
|
54
|
-
def _association_class_name(name)
|
55
|
-
if class_name = _association_for(name).fetch(:class_name)
|
56
|
-
begin
|
57
|
-
class_name.constantize
|
58
|
-
rescue NameError
|
59
|
-
raise MisconfiguredAssociation,
|
60
|
-
"#{self}##{_association_type(name)} #{name} has a class_name specified that does not exist."
|
61
|
-
end
|
62
|
-
else
|
63
|
-
raise MisconfiguredAssociation,
|
64
|
-
"#{self}##{_association_type(name)} #{name} is missing an explicit `:class_name` value."
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# :nodoc:
|
69
|
-
def associate(type, attrs)
|
70
|
-
options = attrs.extract_options!
|
71
|
-
|
72
|
-
self._associations = _associations.dup
|
73
|
-
|
74
|
-
attrs.each do |attr|
|
75
|
-
unless method_defined?(attr)
|
76
|
-
define_method attr do
|
77
|
-
read_association(attr)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
if type == :has_many
|
82
|
-
unless method_defined?(:"#{attr.to_s.singularize}_ids")
|
83
|
-
define_method :"#{attr.to_s.singularize}_ids" do
|
84
|
-
if objs = read_association(attr)
|
85
|
-
objs.collect {|o| o.send(o.primary_key)}
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
else
|
90
|
-
unless method_defined?(:"#{attr.to_s.singularize}_id")
|
91
|
-
define_method :"#{attr.to_s.singularize}_id" do
|
92
|
-
if obj = read_association(attr)
|
93
|
-
obj.send(obj.primary_key)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
unless method_defined?(:"#{attr}=")
|
99
|
-
define_method :"#{attr}=" do |val|
|
100
|
-
val = [val].flatten if type == :has_many && !val.nil?
|
101
|
-
set_association(attr, val)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
self._associations[attr] = {type: type, class_name: options.delete(:class_name), options: options}
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# :nodoc:
|
111
|
-
def each_association(&block)
|
112
|
-
self.class._associations.dup.each do |name, options|
|
113
|
-
association = self.send(name)
|
114
|
-
|
115
|
-
if block_given?
|
116
|
-
block.call(name, association, options[:options])
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# Helper method that returns the names of defined associations.
|
122
|
-
#
|
123
|
-
# @return [Array<Symbol>] a list of association names
|
124
|
-
def association_names
|
125
|
-
self.class._associations.keys
|
126
|
-
end
|
127
|
-
|
128
|
-
protected
|
129
|
-
|
130
|
-
|
131
|
-
# Read the specified association.
|
132
|
-
#
|
133
|
-
# @param name [Symbol, String] the association name, `:users` or `:author`
|
134
|
-
#
|
135
|
-
# @return [Array, Object, nil] the value(s) of that association.
|
136
|
-
def read_association(name)
|
137
|
-
type = _association_type(name)
|
138
|
-
_associations.fetch(name, nil)
|
139
|
-
end
|
140
|
-
|
141
|
-
# Set values for the key'd association.
|
142
|
-
#
|
143
|
-
# @param key [Symbol] the association name, `:users` or `:author`
|
144
|
-
# @param value the value to set on the specified association
|
145
|
-
def set_association(key, value)
|
146
|
-
_associations[key.to_sym] = _cast_association(key, value)
|
147
|
-
end
|
148
|
-
|
149
|
-
|
150
|
-
# Helper method that verifies a given association exists.
|
151
|
-
#
|
152
|
-
# @param attr_name [String, Symbol] the association name
|
153
|
-
#
|
154
|
-
# @return [true, false]
|
155
|
-
def has_association?(attr_name)
|
156
|
-
_associations.has_key?(attr_name.to_sym)
|
157
|
-
end
|
158
|
-
|
159
|
-
private
|
160
|
-
|
161
|
-
# :nodoc:
|
162
|
-
def _cast_association(name, value)
|
163
|
-
return if value.is_a?(Array) && _association_type(name) != :has_many
|
164
|
-
return value if value.nil?
|
165
|
-
|
166
|
-
association_class = _association_class_name(name)
|
167
|
-
|
168
|
-
case value
|
169
|
-
when association_class
|
170
|
-
value
|
171
|
-
when Array
|
172
|
-
value.collect {|i| _cast_association(name, i) }
|
173
|
-
when Hash
|
174
|
-
association_class.new(value)
|
175
|
-
when NilClass
|
176
|
-
nil
|
177
|
-
else
|
178
|
-
association_class.new({association_class.primary_key => value})
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
# :nodoc:
|
183
|
-
def _association_for(name)
|
184
|
-
self.class._association_for(name)
|
185
|
-
end
|
186
|
-
|
187
|
-
# :nodoc:
|
188
|
-
def _association_type(name)
|
189
|
-
self.class._association_type(name)
|
190
|
-
end
|
191
|
-
|
192
|
-
# :nodoc:
|
193
|
-
def _association_class_name(name)
|
194
|
-
self.class._association_class_name(name)
|
195
|
-
end
|
196
|
-
|
197
|
-
# :nodoc:
|
198
|
-
def _associations
|
199
|
-
@associations ||= {}
|
200
|
-
end
|
201
|
-
|
202
|
-
end
|
203
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Resource
|
2
|
-
module AttributesConcern
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
include ActiveModel::AttributeMethods
|
6
|
-
include ActiveModel::Dirty
|
7
|
-
|
8
|
-
included do
|
9
|
-
attr_reader :attributes
|
10
|
-
end
|
11
|
-
|
12
|
-
def attributes=(attrs={})
|
13
|
-
@attributes ||= {}
|
14
|
-
|
15
|
-
return @attributes unless attrs.present?
|
16
|
-
attrs.each do |key, value|
|
17
|
-
set_attribute(key, value)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def update_attributes(attrs={})
|
22
|
-
self.attributes = attrs
|
23
|
-
# FIXME save
|
24
|
-
end
|
25
|
-
|
26
|
-
def persisted?
|
27
|
-
!self.to_param.blank?
|
28
|
-
end
|
29
|
-
|
30
|
-
def to_param
|
31
|
-
attributes.fetch(primary_key, '').to_s
|
32
|
-
end
|
33
|
-
|
34
|
-
# def [](key)
|
35
|
-
# read_attribute(key)
|
36
|
-
# end
|
37
|
-
|
38
|
-
# def []=(key, value)
|
39
|
-
# set_attribute(key, value)
|
40
|
-
# end
|
41
|
-
|
42
|
-
alias :respond_to_without_attributes? :respond_to?
|
43
|
-
def respond_to?(method, include_private_methods=false)
|
44
|
-
if super
|
45
|
-
true
|
46
|
-
elsif !include_private_methods && super(method, true)
|
47
|
-
# If we're here then we haven't found among non-private methods
|
48
|
-
# but found among all methods. Which means that the given method is private.
|
49
|
-
false
|
50
|
-
else
|
51
|
-
has_attribute?(method)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def read_attribute(name)
|
58
|
-
attributes.fetch(name, nil)
|
59
|
-
end
|
60
|
-
|
61
|
-
def set_attribute(key, value)
|
62
|
-
attributes[key.to_sym] = value
|
63
|
-
end
|
64
|
-
|
65
|
-
def has_attribute?(attr_name)
|
66
|
-
attributes.has_key?(attr_name.to_sym)
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer
|
2
|
-
module ConnectionConcern
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
module ClassMethods
|
6
|
-
def parser_class
|
7
|
-
@parser ||= Parser
|
8
|
-
end
|
9
|
-
|
10
|
-
def parse(response)
|
11
|
-
parser = parser_class.new(self, response)
|
12
|
-
|
13
|
-
if response.status && response.status == 204
|
14
|
-
true
|
15
|
-
else
|
16
|
-
parser.build
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# :nodoc:
|
21
|
-
def _run_request(query_object)
|
22
|
-
parse(_connection.send(query_object.request_method, query_object.path, query_object.params, query_object.headers))
|
23
|
-
end
|
24
|
-
|
25
|
-
# :nodoc:
|
26
|
-
def _connection(reload=false)
|
27
|
-
self.connection = nil if !!reload
|
28
|
-
self.connection ||= begin
|
29
|
-
Faraday.new(url: self.host, ssl: self.ssl) do |conn|
|
30
|
-
conn.request :json
|
31
|
-
conn.request :request_headers, accept: "application/json"
|
32
|
-
|
33
|
-
yield(conn) if block_given?
|
34
|
-
|
35
|
-
conn.use Middleware::RequestTimeout
|
36
|
-
conn.use Middleware::ParseJson
|
37
|
-
|
38
|
-
conn.use Middleware::RaiseError
|
39
|
-
conn.adapter Faraday.default_adapter
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def is_valid?
|
47
|
-
errors.empty?
|
48
|
-
end
|
49
|
-
|
50
|
-
def save
|
51
|
-
query = persisted? ?
|
52
|
-
Query::Update.new(self.class, self.serializable_hash) :
|
53
|
-
Query::Create.new(self.class, self.serializable_hash)
|
54
|
-
|
55
|
-
results = run_request(query)
|
56
|
-
|
57
|
-
if self.errors.empty?
|
58
|
-
self.attributes = results.first.attributes
|
59
|
-
true
|
60
|
-
else
|
61
|
-
false
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def destroy
|
66
|
-
if run_request(Query::Delete.new(self.class, self.serializable_hash))
|
67
|
-
self.attributes.clear
|
68
|
-
true
|
69
|
-
else
|
70
|
-
false
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
# :nodoc:
|
77
|
-
def run_request(*args)
|
78
|
-
begin
|
79
|
-
self.errors.clear
|
80
|
-
request = self.class._run_request(*args)
|
81
|
-
rescue JSONAPI::Consumer::Errors::BadRequest => e
|
82
|
-
e.errors.map do |error|
|
83
|
-
process_error(error.dup)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# :nodoc:
|
89
|
-
def process_error(err)
|
90
|
-
field = err.fetch('path', '')
|
91
|
-
attr = field.match(/\A\/(\w+)\z/)
|
92
|
-
if attr[1] && has_attribute?(attr[1])
|
93
|
-
self.errors.add(attr[1].to_sym, err.fetch('detail', ''))
|
94
|
-
else
|
95
|
-
self.errors.add(:base, err.fetch('detail', ''))
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Resource
|
2
|
-
module FindersConcern
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
module ClassMethods
|
6
|
-
def all(options={})
|
7
|
-
_run_request(JSONAPI::Consumer::Query::Find.new(self, options))
|
8
|
-
end
|
9
|
-
|
10
|
-
def find(options)
|
11
|
-
options = {self.primary_key => options} unless options.is_a?(Hash)
|
12
|
-
_run_request(JSONAPI::Consumer::Query::Find.new(self, options))
|
13
|
-
end
|
14
|
-
|
15
|
-
def primary_key
|
16
|
-
@primary_key ||= :id
|
17
|
-
end
|
18
|
-
|
19
|
-
def primary_key=(val)
|
20
|
-
@primary_key = val.to_sym
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def primary_key
|
25
|
-
self.class.primary_key
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Resource
|
2
|
-
module ObjectBuildConcern
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
class_attribute :request_new_object_on_build
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
|
11
|
-
# If class attribute `request_new_object_on_build`:
|
12
|
-
#
|
13
|
-
# True:
|
14
|
-
# will send a request to `{path}/new` to get an attributes list
|
15
|
-
#
|
16
|
-
# False:
|
17
|
-
# acts as an alias for `new`
|
18
|
-
#
|
19
|
-
def build
|
20
|
-
if !!self.request_new_object_on_build
|
21
|
-
_run_request(JSONAPI::Consumer::Query::New.new(self, {})).first
|
22
|
-
else
|
23
|
-
new
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
module JSONAPI::Consumer::Resource
|
2
|
-
module SerializerConcern
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
def serializable_hash(options={})
|
6
|
-
@hash = persisted? ? attributes : attributes.except(self.class.primary_key)
|
7
|
-
|
8
|
-
self.each_association do |name, association, options|
|
9
|
-
@hash[:links] ||= {}
|
10
|
-
|
11
|
-
if association.respond_to?(:each) or _association_type(name) == :has_many
|
12
|
-
add_links(name, association, options)
|
13
|
-
else
|
14
|
-
add_link(name, association, options)
|
15
|
-
end
|
16
|
-
@hash.delete(:links) if remove_links?
|
17
|
-
end
|
18
|
-
|
19
|
-
@hash
|
20
|
-
end
|
21
|
-
|
22
|
-
def add_links(name, association, options)
|
23
|
-
@hash[:links][name] ||= []
|
24
|
-
@hash[:links][name] += (association || []).map do |obj|
|
25
|
-
case obj.class
|
26
|
-
when String, Integer
|
27
|
-
obj
|
28
|
-
else
|
29
|
-
obj.to_param
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def add_link(name, association, options)
|
35
|
-
return if association.nil?
|
36
|
-
|
37
|
-
@hash[:links][name] = case association.class
|
38
|
-
when String, Integer
|
39
|
-
association
|
40
|
-
else
|
41
|
-
association.to_param
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def to_json(options={})
|
46
|
-
serializable_hash(options).to_json
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def remove_links?
|
52
|
-
if persisted?
|
53
|
-
false
|
54
|
-
else # not persisted, new object
|
55
|
-
if @hash[:links].length == 0 or @hash[:links].values.flatten.empty?
|
56
|
-
true
|
57
|
-
else
|
58
|
-
false
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/spec/fixtures/.gitkeep
DELETED
File without changes
|