jsonapi-consumer 0.1.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|