jsonapi-resources 0.9.12 → 0.10.7
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/LICENSE.txt +1 -1
- data/README.md +34 -11
- data/lib/bug_report_templates/rails_5_latest.rb +125 -0
- data/lib/bug_report_templates/rails_5_master.rb +140 -0
- data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +27 -0
- data/lib/jsonapi/active_relation/join_manager.rb +303 -0
- data/lib/jsonapi/active_relation_resource.rb +884 -0
- data/lib/jsonapi/acts_as_resource_controller.rb +122 -106
- data/lib/jsonapi/basic_resource.rb +1162 -0
- data/lib/jsonapi/cached_response_fragment.rb +127 -0
- data/lib/jsonapi/compiled_json.rb +11 -1
- data/lib/jsonapi/configuration.rb +57 -8
- data/lib/jsonapi/error.rb +27 -0
- data/lib/jsonapi/error_codes.rb +2 -0
- data/lib/jsonapi/exceptions.rb +63 -40
- data/lib/jsonapi/formatter.rb +3 -3
- data/lib/jsonapi/include_directives.rb +18 -75
- data/lib/jsonapi/link_builder.rb +18 -25
- data/lib/jsonapi/operation.rb +16 -5
- data/lib/jsonapi/operation_result.rb +73 -15
- data/lib/jsonapi/paginator.rb +17 -0
- data/lib/jsonapi/path.rb +43 -0
- data/lib/jsonapi/path_segment.rb +76 -0
- data/lib/jsonapi/processor.rb +246 -111
- data/lib/jsonapi/relationship.rb +117 -24
- data/lib/jsonapi/request_parser.rb +383 -396
- data/lib/jsonapi/resource.rb +3 -1376
- data/lib/jsonapi/resource_controller_metal.rb +3 -0
- data/lib/jsonapi/resource_fragment.rb +47 -0
- data/lib/jsonapi/resource_id_tree.rb +112 -0
- data/lib/jsonapi/resource_identity.rb +42 -0
- data/lib/jsonapi/resource_serializer.rb +124 -286
- data/lib/jsonapi/resource_set.rb +176 -0
- data/lib/jsonapi/resources/railtie.rb +9 -0
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +104 -87
- data/lib/jsonapi/routing_ext.rb +19 -21
- data/lib/jsonapi-resources.rb +20 -4
- data/lib/tasks/check_upgrade.rake +52 -0
- metadata +34 -31
- data/lib/jsonapi/cached_resource_fragment.rb +0 -127
- data/lib/jsonapi/operation_dispatcher.rb +0 -88
- data/lib/jsonapi/operation_results.rb +0 -35
- data/lib/jsonapi/relationship_builder.rb +0 -167
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-resources
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Gebhardt
|
8
8
|
- Larry Gebhardt
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-03-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '1.17'
|
21
21
|
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '1.17'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rake
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,16 +43,22 @@ dependencies:
|
|
43
43
|
name: minitest
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
48
|
+
version: '5.10'
|
49
|
+
- - "!="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 5.10.2
|
49
52
|
type: :development
|
50
53
|
prerelease: false
|
51
54
|
version_requirements: !ruby/object:Gem::Requirement
|
52
55
|
requirements:
|
53
|
-
- - "
|
56
|
+
- - "~>"
|
54
57
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
58
|
+
version: '5.10'
|
59
|
+
- - "!="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.10.2
|
56
62
|
- !ruby/object:Gem::Dependency
|
57
63
|
name: minitest-spec-rails
|
58
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,20 +129,6 @@ dependencies:
|
|
123
129
|
- - ">="
|
124
130
|
- !ruby/object:Gem::Version
|
125
131
|
version: '0'
|
126
|
-
- !ruby/object:Gem::Dependency
|
127
|
-
name: memory_profiler
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
129
|
-
requirements:
|
130
|
-
- - ">="
|
131
|
-
- !ruby/object:Gem::Version
|
132
|
-
version: '0'
|
133
|
-
type: :development
|
134
|
-
prerelease: false
|
135
|
-
version_requirements: !ruby/object:Gem::Requirement
|
136
|
-
requirements:
|
137
|
-
- - ">="
|
138
|
-
- !ruby/object:Gem::Version
|
139
|
-
version: '0'
|
140
132
|
- !ruby/object:Gem::Dependency
|
141
133
|
name: activerecord
|
142
134
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,14 +182,20 @@ extra_rdoc_files: []
|
|
190
182
|
files:
|
191
183
|
- LICENSE.txt
|
192
184
|
- README.md
|
185
|
+
- lib/bug_report_templates/rails_5_latest.rb
|
186
|
+
- lib/bug_report_templates/rails_5_master.rb
|
193
187
|
- lib/generators/jsonapi/USAGE
|
194
188
|
- lib/generators/jsonapi/controller_generator.rb
|
195
189
|
- lib/generators/jsonapi/resource_generator.rb
|
196
190
|
- lib/generators/jsonapi/templates/jsonapi_controller.rb
|
197
191
|
- lib/generators/jsonapi/templates/jsonapi_resource.rb
|
198
192
|
- lib/jsonapi-resources.rb
|
193
|
+
- lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb
|
194
|
+
- lib/jsonapi/active_relation/join_manager.rb
|
195
|
+
- lib/jsonapi/active_relation_resource.rb
|
199
196
|
- lib/jsonapi/acts_as_resource_controller.rb
|
200
|
-
- lib/jsonapi/
|
197
|
+
- lib/jsonapi/basic_resource.rb
|
198
|
+
- lib/jsonapi/cached_response_fragment.rb
|
201
199
|
- lib/jsonapi/callbacks.rb
|
202
200
|
- lib/jsonapi/compiled_json.rb
|
203
201
|
- lib/jsonapi/configuration.rb
|
@@ -210,26 +208,31 @@ files:
|
|
210
208
|
- lib/jsonapi/mime_types.rb
|
211
209
|
- lib/jsonapi/naive_cache.rb
|
212
210
|
- lib/jsonapi/operation.rb
|
213
|
-
- lib/jsonapi/operation_dispatcher.rb
|
214
211
|
- lib/jsonapi/operation_result.rb
|
215
|
-
- lib/jsonapi/operation_results.rb
|
216
212
|
- lib/jsonapi/paginator.rb
|
213
|
+
- lib/jsonapi/path.rb
|
214
|
+
- lib/jsonapi/path_segment.rb
|
217
215
|
- lib/jsonapi/processor.rb
|
218
216
|
- lib/jsonapi/relationship.rb
|
219
|
-
- lib/jsonapi/relationship_builder.rb
|
220
217
|
- lib/jsonapi/request_parser.rb
|
221
218
|
- lib/jsonapi/resource.rb
|
222
219
|
- lib/jsonapi/resource_controller.rb
|
223
220
|
- lib/jsonapi/resource_controller_metal.rb
|
221
|
+
- lib/jsonapi/resource_fragment.rb
|
222
|
+
- lib/jsonapi/resource_id_tree.rb
|
223
|
+
- lib/jsonapi/resource_identity.rb
|
224
224
|
- lib/jsonapi/resource_serializer.rb
|
225
|
+
- lib/jsonapi/resource_set.rb
|
226
|
+
- lib/jsonapi/resources/railtie.rb
|
225
227
|
- lib/jsonapi/resources/version.rb
|
226
228
|
- lib/jsonapi/response_document.rb
|
227
229
|
- lib/jsonapi/routing_ext.rb
|
230
|
+
- lib/tasks/check_upgrade.rake
|
228
231
|
homepage: https://github.com/cerebris/jsonapi-resources
|
229
232
|
licenses:
|
230
233
|
- MIT
|
231
234
|
metadata: {}
|
232
|
-
post_install_message:
|
235
|
+
post_install_message:
|
233
236
|
rdoc_options: []
|
234
237
|
require_paths:
|
235
238
|
- lib
|
@@ -237,15 +240,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
237
240
|
requirements:
|
238
241
|
- - ">="
|
239
242
|
- !ruby/object:Gem::Version
|
240
|
-
version: '2.
|
243
|
+
version: '2.3'
|
241
244
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
242
245
|
requirements:
|
243
246
|
- - ">="
|
244
247
|
- !ruby/object:Gem::Version
|
245
248
|
version: '0'
|
246
249
|
requirements: []
|
247
|
-
rubygems_version: 3.
|
248
|
-
signing_key:
|
250
|
+
rubygems_version: 3.1.6
|
251
|
+
signing_key:
|
249
252
|
specification_version: 4
|
250
253
|
summary: Easily support JSON API in Rails.
|
251
254
|
test_files: []
|
@@ -1,127 +0,0 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
class CachedResourceFragment
|
3
|
-
def self.fetch_fragments(resource_klass, serializer, context, cache_ids)
|
4
|
-
serializer_config_key = serializer.config_key(resource_klass).gsub("/", "_")
|
5
|
-
context_json = resource_klass.attribute_caching_context(context).to_json
|
6
|
-
context_b64 = JSONAPI.configuration.resource_cache_digest_function.call(context_json)
|
7
|
-
context_key = "ATTR-CTX-#{context_b64.gsub("/", "_")}"
|
8
|
-
|
9
|
-
results = self.lookup(resource_klass, serializer_config_key, context, context_key, cache_ids)
|
10
|
-
|
11
|
-
miss_ids = results.select{|k,v| v.nil? }.keys
|
12
|
-
unless miss_ids.empty?
|
13
|
-
find_filters = {resource_klass._primary_key => miss_ids.uniq}
|
14
|
-
find_options = {context: context}
|
15
|
-
resource_klass.find(find_filters, find_options).each do |resource|
|
16
|
-
(id, cr) = write(resource_klass, resource, serializer, serializer_config_key, context, context_key)
|
17
|
-
results[id] = cr
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
if JSONAPI.configuration.resource_cache_usage_report_function
|
22
|
-
JSONAPI.configuration.resource_cache_usage_report_function.call(
|
23
|
-
resource_klass.name,
|
24
|
-
cache_ids.size - miss_ids.size,
|
25
|
-
miss_ids.size
|
26
|
-
)
|
27
|
-
end
|
28
|
-
|
29
|
-
return results
|
30
|
-
end
|
31
|
-
|
32
|
-
attr_reader :resource_klass, :id, :type, :context, :fetchable_fields, :relationships,
|
33
|
-
:links_json, :attributes_json, :meta_json,
|
34
|
-
:preloaded_fragments
|
35
|
-
|
36
|
-
def initialize(resource_klass, id, type, context, fetchable_fields, relationships,
|
37
|
-
links_json, attributes_json, meta_json)
|
38
|
-
@resource_klass = resource_klass
|
39
|
-
@id = id
|
40
|
-
@type = type
|
41
|
-
@context = context
|
42
|
-
@fetchable_fields = Set.new(fetchable_fields)
|
43
|
-
|
44
|
-
# Relationships left uncompiled because we'll often want to insert included ids on retrieval
|
45
|
-
@relationships = relationships
|
46
|
-
|
47
|
-
@links_json = CompiledJson.of(links_json)
|
48
|
-
@attributes_json = CompiledJson.of(attributes_json)
|
49
|
-
@meta_json = CompiledJson.of(meta_json)
|
50
|
-
|
51
|
-
# A hash of hashes
|
52
|
-
@preloaded_fragments ||= Hash.new
|
53
|
-
end
|
54
|
-
|
55
|
-
def to_cache_value
|
56
|
-
{
|
57
|
-
id: id,
|
58
|
-
type: type,
|
59
|
-
fetchable: fetchable_fields,
|
60
|
-
rels: relationships,
|
61
|
-
links: links_json.try(:to_s),
|
62
|
-
attrs: attributes_json.try(:to_s),
|
63
|
-
meta: meta_json.try(:to_s)
|
64
|
-
}
|
65
|
-
end
|
66
|
-
|
67
|
-
def to_real_resource
|
68
|
-
rs = Resource.resource_for(self.type).find_by_keys([self.id], {context: self.context})
|
69
|
-
return rs.try(:first)
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def self.lookup(resource_klass, serializer_config_key, context, context_key, cache_ids)
|
75
|
-
type = resource_klass._type
|
76
|
-
|
77
|
-
keys = cache_ids.map do |(id, cache_key)|
|
78
|
-
[type, id, cache_key, serializer_config_key, context_key]
|
79
|
-
end
|
80
|
-
|
81
|
-
hits = JSONAPI.configuration.resource_cache.read_multi(*keys).reject{|_,v| v.nil? }
|
82
|
-
return keys.each_with_object({}) do |key, hash|
|
83
|
-
(_, id, _, _) = key
|
84
|
-
if hits.has_key?(key)
|
85
|
-
hash[id] = self.from_cache_value(resource_klass, context, hits[key])
|
86
|
-
else
|
87
|
-
hash[id] = nil
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.from_cache_value(resource_klass, context, h)
|
93
|
-
new(
|
94
|
-
resource_klass,
|
95
|
-
h.fetch(:id),
|
96
|
-
h.fetch(:type),
|
97
|
-
context,
|
98
|
-
h.fetch(:fetchable),
|
99
|
-
h.fetch(:rels, nil),
|
100
|
-
h.fetch(:links, nil),
|
101
|
-
h.fetch(:attrs, nil),
|
102
|
-
h.fetch(:meta, nil)
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
def self.write(resource_klass, resource, serializer, serializer_config_key, context, context_key)
|
107
|
-
(id, cache_key) = resource.cache_id
|
108
|
-
json = serializer.object_hash(resource) # No inclusions passed to object_hash
|
109
|
-
cr = self.new(
|
110
|
-
resource_klass,
|
111
|
-
json['id'],
|
112
|
-
json['type'],
|
113
|
-
context,
|
114
|
-
resource.fetchable_fields,
|
115
|
-
json['relationships'],
|
116
|
-
json['links'],
|
117
|
-
json['attributes'],
|
118
|
-
json['meta']
|
119
|
-
)
|
120
|
-
|
121
|
-
key = [resource_klass._type, id, cache_key, serializer_config_key, context_key]
|
122
|
-
JSONAPI.configuration.resource_cache.write(key, cr.to_cache_value)
|
123
|
-
return [id, cr]
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
class OperationDispatcher
|
3
|
-
|
4
|
-
def initialize(transaction: lambda { |&block| block.yield },
|
5
|
-
rollback: lambda { },
|
6
|
-
server_error_callbacks: [])
|
7
|
-
|
8
|
-
@transaction = transaction
|
9
|
-
@rollback = rollback
|
10
|
-
@server_error_callbacks = server_error_callbacks
|
11
|
-
end
|
12
|
-
|
13
|
-
def process(operations)
|
14
|
-
results = JSONAPI::OperationResults.new
|
15
|
-
|
16
|
-
# Use transactions if more than one operation and if one of the operations can be transactional
|
17
|
-
# Even if transactional transactions won't be used unless the derived OperationsProcessor supports them.
|
18
|
-
transactional = false
|
19
|
-
|
20
|
-
operations.each do |operation|
|
21
|
-
transactional |= operation.transactional?
|
22
|
-
end if JSONAPI.configuration.allow_transactions
|
23
|
-
|
24
|
-
transaction(transactional) do
|
25
|
-
# Links and meta data global to the set of operations
|
26
|
-
operations_meta = {}
|
27
|
-
operations_links = {}
|
28
|
-
operations.each do |operation|
|
29
|
-
results.add_result(process_operation(operation))
|
30
|
-
rollback(transactional) if results.has_errors?
|
31
|
-
end
|
32
|
-
results.meta = operations_meta
|
33
|
-
results.links = operations_links
|
34
|
-
end
|
35
|
-
results
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def transaction(transactional)
|
41
|
-
if transactional
|
42
|
-
@transaction.call do
|
43
|
-
yield
|
44
|
-
end
|
45
|
-
else
|
46
|
-
yield
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def rollback(transactional)
|
51
|
-
if transactional
|
52
|
-
@rollback.call
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def process_operation(operation)
|
57
|
-
with_default_handling do
|
58
|
-
operation.process
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def with_default_handling(&block)
|
63
|
-
block.yield
|
64
|
-
rescue => e
|
65
|
-
if JSONAPI.configuration.exception_class_whitelisted?(e)
|
66
|
-
raise e
|
67
|
-
else
|
68
|
-
@server_error_callbacks.each { |callback|
|
69
|
-
safe_run_callback(callback, e)
|
70
|
-
}
|
71
|
-
|
72
|
-
internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e)
|
73
|
-
Rails.logger.error { "Internal Server Error: #{e.message} #{e.backtrace.join("\n")}" }
|
74
|
-
return JSONAPI::ErrorsOperationResult.new(internal_server_error.errors[0].code, internal_server_error.errors)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def safe_run_callback(callback, error)
|
79
|
-
begin
|
80
|
-
callback.call(error)
|
81
|
-
rescue => e
|
82
|
-
Rails.logger.error { "Error in error handling callback: #{e.message} #{e.backtrace.join("\n")}" }
|
83
|
-
internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e)
|
84
|
-
return JSONAPI::ErrorsOperationResult.new(internal_server_error.errors[0].code, internal_server_error.errors)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
class OperationResults
|
3
|
-
attr_accessor :results
|
4
|
-
attr_accessor :meta
|
5
|
-
attr_accessor :links
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@results = []
|
9
|
-
@has_errors = false
|
10
|
-
@meta = {}
|
11
|
-
@links = {}
|
12
|
-
end
|
13
|
-
|
14
|
-
def add_result(result)
|
15
|
-
@has_errors = true if result.is_a?(JSONAPI::ErrorsOperationResult)
|
16
|
-
@results.push(result)
|
17
|
-
end
|
18
|
-
|
19
|
-
def has_errors?
|
20
|
-
@has_errors
|
21
|
-
end
|
22
|
-
|
23
|
-
def all_errors
|
24
|
-
errors = []
|
25
|
-
if @has_errors
|
26
|
-
@results.each do |result|
|
27
|
-
if result.is_a?(JSONAPI::ErrorsOperationResult)
|
28
|
-
errors.concat(result.errors)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
errors
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,167 +0,0 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
class RelationshipBuilder
|
3
|
-
attr_reader :model_class, :options, :relationship_class
|
4
|
-
delegate :register_relationship, to: :@resource_class
|
5
|
-
|
6
|
-
def initialize(relationship_class, model_class, options)
|
7
|
-
@relationship_class = relationship_class
|
8
|
-
@model_class = model_class
|
9
|
-
@resource_class = options[:parent_resource]
|
10
|
-
@options = options
|
11
|
-
end
|
12
|
-
|
13
|
-
def define_relationship_methods(relationship_name)
|
14
|
-
# Initialize from an ActiveRecord model's properties
|
15
|
-
if model_class && model_class.ancestors.collect{|ancestor| ancestor.name}.include?('ActiveRecord::Base')
|
16
|
-
model_association = model_class.reflect_on_association(relationship_name)
|
17
|
-
if model_association
|
18
|
-
options[:class_name] ||= model_association.class_name
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
relationship = register_relationship(
|
23
|
-
relationship_name,
|
24
|
-
relationship_class.new(relationship_name, options)
|
25
|
-
)
|
26
|
-
|
27
|
-
foreign_key = define_foreign_key_setter(relationship.foreign_key)
|
28
|
-
|
29
|
-
case relationship
|
30
|
-
when JSONAPI::Relationship::ToOne
|
31
|
-
associated = define_resource_relationship_accessor(:one, relationship_name)
|
32
|
-
args = [relationship, foreign_key, associated, relationship_name]
|
33
|
-
|
34
|
-
relationship.belongs_to? ? build_belongs_to(*args) : build_has_one(*args)
|
35
|
-
when JSONAPI::Relationship::ToMany
|
36
|
-
associated = define_resource_relationship_accessor(:many, relationship_name)
|
37
|
-
|
38
|
-
build_to_many(relationship, foreign_key, associated, relationship_name)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def define_foreign_key_setter(foreign_key)
|
43
|
-
define_on_resource "#{foreign_key}=" do |value|
|
44
|
-
@model.method("#{foreign_key}=").call(value)
|
45
|
-
end
|
46
|
-
foreign_key
|
47
|
-
end
|
48
|
-
|
49
|
-
def define_resource_relationship_accessor(type, relationship_name)
|
50
|
-
associated_records_method_name = {
|
51
|
-
one: "record_for_#{relationship_name}",
|
52
|
-
many: "records_for_#{relationship_name}"
|
53
|
-
}
|
54
|
-
.fetch(type)
|
55
|
-
|
56
|
-
define_on_resource associated_records_method_name do |options = {}|
|
57
|
-
relationship = self.class._relationships[relationship_name]
|
58
|
-
relation_name = relationship.relation_name(context: @context)
|
59
|
-
records = records_for(relation_name)
|
60
|
-
|
61
|
-
resource_klass = relationship.resource_klass
|
62
|
-
|
63
|
-
records = resource_klass.apply_includes(records, options)
|
64
|
-
|
65
|
-
filters = options.fetch(:filters, {})
|
66
|
-
unless filters.nil? || filters.empty?
|
67
|
-
records = resource_klass.apply_filters(records, filters, options)
|
68
|
-
end
|
69
|
-
|
70
|
-
sort_criteria = options.fetch(:sort_criteria, {})
|
71
|
-
order_options = relationship.resource_klass.construct_order_options(sort_criteria)
|
72
|
-
records = resource_klass.apply_sort(records, order_options, @context)
|
73
|
-
|
74
|
-
paginator = options[:paginator]
|
75
|
-
if paginator
|
76
|
-
records = resource_klass.apply_pagination(records, paginator, order_options)
|
77
|
-
end
|
78
|
-
|
79
|
-
records
|
80
|
-
end
|
81
|
-
|
82
|
-
associated_records_method_name
|
83
|
-
end
|
84
|
-
|
85
|
-
def build_belongs_to(relationship, foreign_key, associated_records_method_name, relationship_name)
|
86
|
-
# Calls method matching foreign key name on model instance
|
87
|
-
define_on_resource foreign_key do
|
88
|
-
@model.method(foreign_key).call
|
89
|
-
end
|
90
|
-
|
91
|
-
# Returns instantiated related resource object or nil
|
92
|
-
define_on_resource relationship_name do |options = {}|
|
93
|
-
relationship = self.class._relationships[relationship_name]
|
94
|
-
|
95
|
-
if relationship.polymorphic?
|
96
|
-
associated_model = public_send(associated_records_method_name)
|
97
|
-
resource_klass = self.class.resource_for_model(associated_model) if associated_model
|
98
|
-
return resource_klass.new(associated_model, @context) if resource_klass
|
99
|
-
else
|
100
|
-
resource_klass = relationship.resource_klass
|
101
|
-
if resource_klass
|
102
|
-
associated_model = public_send(associated_records_method_name)
|
103
|
-
return associated_model ? resource_klass.new(associated_model, @context) : nil
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def build_has_one(relationship, foreign_key, associated_records_method_name, relationship_name)
|
110
|
-
# Returns primary key name of related resource class
|
111
|
-
define_on_resource foreign_key do
|
112
|
-
relationship = self.class._relationships[relationship_name]
|
113
|
-
|
114
|
-
record = public_send(associated_records_method_name)
|
115
|
-
return nil if record.nil?
|
116
|
-
record.public_send(relationship.resource_klass._primary_key)
|
117
|
-
end
|
118
|
-
|
119
|
-
# Returns instantiated related resource object or nil
|
120
|
-
define_on_resource relationship_name do |options = {}|
|
121
|
-
relationship = self.class._relationships[relationship_name]
|
122
|
-
|
123
|
-
if relationship.polymorphic?
|
124
|
-
associated_model = public_send(associated_records_method_name)
|
125
|
-
resource_klass = self.class.resource_for_model(associated_model) if associated_model
|
126
|
-
return resource_klass.new(associated_model, @context) if resource_klass && associated_model
|
127
|
-
else
|
128
|
-
resource_klass = relationship.resource_klass
|
129
|
-
if resource_klass
|
130
|
-
associated_model = public_send(associated_records_method_name)
|
131
|
-
return associated_model ? resource_klass.new(associated_model, @context) : nil
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def build_to_many(relationship, foreign_key, associated_records_method_name, relationship_name)
|
138
|
-
# Returns array of primary keys of related resource classes
|
139
|
-
define_on_resource foreign_key do
|
140
|
-
records = public_send(associated_records_method_name)
|
141
|
-
return records.collect do |record|
|
142
|
-
record.public_send(relationship.resource_klass._primary_key)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# Returns array of instantiated related resource objects
|
147
|
-
define_on_resource relationship_name do |options = {}|
|
148
|
-
relationship = self.class._relationships[relationship_name]
|
149
|
-
|
150
|
-
resource_klass = relationship.resource_klass
|
151
|
-
records = public_send(associated_records_method_name, options)
|
152
|
-
|
153
|
-
return records.collect do |record|
|
154
|
-
if relationship.polymorphic?
|
155
|
-
resource_klass = self.class.resource_for_model(record)
|
156
|
-
end
|
157
|
-
resource_klass.new(record, @context)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def define_on_resource(method_name, &block)
|
163
|
-
return if @resource_class.method_defined?(method_name)
|
164
|
-
@resource_class.inject_method_definition(method_name, block)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|