jsonapi-resources 0.10.0.beta2 → 0.10.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.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0.beta2
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Gebhardt
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-02-11 00:00:00.000000000 Z
12
+ date: 2019-09-30 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: '1.5'
20
+ version: 1.17.3
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: '1.5'
27
+ version: 1.17.3
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -115,6 +115,20 @@ dependencies:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
+ - !ruby/object:Gem::Dependency
119
+ name: database_cleaner
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
118
132
  - !ruby/object:Gem::Dependency
119
133
  name: activerecord
120
134
  requirement: !ruby/object:Gem::Requirement
@@ -176,10 +190,11 @@ files:
176
190
  - lib/generators/jsonapi/templates/jsonapi_controller.rb
177
191
  - lib/generators/jsonapi/templates/jsonapi_resource.rb
178
192
  - lib/jsonapi-resources.rb
179
- - lib/jsonapi/active_relation_resource_finder.rb
180
- - lib/jsonapi/active_relation_resource_finder/adapters/join_left_active_record_adapter.rb
181
- - lib/jsonapi/active_relation_resource_finder/join_tree.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
182
196
  - lib/jsonapi/acts_as_resource_controller.rb
197
+ - lib/jsonapi/basic_resource.rb
183
198
  - lib/jsonapi/cached_response_fragment.rb
184
199
  - lib/jsonapi/callbacks.rb
185
200
  - lib/jsonapi/compiled_json.rb
@@ -208,9 +223,11 @@ files:
208
223
  - lib/jsonapi/resource_identity.rb
209
224
  - lib/jsonapi/resource_serializer.rb
210
225
  - lib/jsonapi/resource_set.rb
226
+ - lib/jsonapi/resources/railtie.rb
211
227
  - lib/jsonapi/resources/version.rb
212
228
  - lib/jsonapi/response_document.rb
213
229
  - lib/jsonapi/routing_ext.rb
230
+ - lib/tasks/check_upgrade.rake
214
231
  homepage: https://github.com/cerebris/jsonapi-resources
215
232
  licenses:
216
233
  - MIT
@@ -223,15 +240,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
240
  requirements:
224
241
  - - ">="
225
242
  - !ruby/object:Gem::Version
226
- version: '2.1'
243
+ version: '2.3'
227
244
  required_rubygems_version: !ruby/object:Gem::Requirement
228
245
  requirements:
229
- - - ">"
246
+ - - ">="
230
247
  - !ruby/object:Gem::Version
231
- version: 1.3.1
248
+ version: '0'
232
249
  requirements: []
233
- rubyforge_project:
234
- rubygems_version: 2.6.14.3
250
+ rubygems_version: 3.0.3
235
251
  signing_key:
236
252
  specification_version: 4
237
253
  summary: Easily support JSON API in Rails.
@@ -1,227 +0,0 @@
1
- module JSONAPI
2
- module ActiveRelationResourceFinder
3
- class JoinTree
4
- # Stores relationship paths starting from the resource_klass. This allows consolidation of duplicate paths from
5
- # relationships, filters and sorts. This enables the determination of table aliases as they are joined.
6
-
7
- attr_reader :resource_klass, :options, :source_relationship, :resource_joins, :joins
8
-
9
- def initialize(resource_klass:,
10
- options: {},
11
- source_relationship: nil,
12
- relationships: nil,
13
- filters: nil,
14
- sort_criteria: nil)
15
-
16
- @resource_klass = resource_klass
17
- @options = options
18
-
19
- @resource_joins = {
20
- root: {
21
- join_type: :root,
22
- resource_klasses: {
23
- resource_klass => {
24
- relationships: {}
25
- }
26
- }
27
- }
28
- }
29
- add_source_relationship(source_relationship)
30
- add_sort_criteria(sort_criteria)
31
- add_filters(filters)
32
- add_relationships(relationships)
33
-
34
- @joins = {}
35
- construct_joins(@resource_joins)
36
- end
37
-
38
- private
39
-
40
- def add_join(path, default_type = :inner, default_polymorphic_join_type = :left)
41
- if source_relationship
42
- if source_relationship.polymorphic?
43
- # Polymorphic paths will come it with the resource_type as the first segment (for example `#documents.comments`)
44
- # We just need to prepend the relationship portion the
45
- sourced_path = "#{source_relationship.name}#{path}"
46
- else
47
- sourced_path = "#{source_relationship.name}.#{path}"
48
- end
49
- else
50
- sourced_path = path
51
- end
52
-
53
- join_tree, _field = parse_path_to_tree(sourced_path, resource_klass, default_type, default_polymorphic_join_type)
54
-
55
- @resource_joins[:root].deep_merge!(join_tree) { |key, val, other_val|
56
- if key == :join_type
57
- if val == other_val
58
- val
59
- else
60
- :inner
61
- end
62
- end
63
- }
64
- end
65
-
66
- def process_path_to_tree(path_segments, resource_klass, default_join_type, default_polymorphic_join_type)
67
- node = {
68
- resource_klasses: {
69
- resource_klass => {
70
- relationships: {}
71
- }
72
- }
73
- }
74
-
75
- segment = path_segments.shift
76
-
77
- if segment.is_a?(PathSegment::Relationship)
78
- node[:resource_klasses][resource_klass][:relationships][segment.relationship] ||= {}
79
-
80
- # join polymorphic as left joins
81
- node[:resource_klasses][resource_klass][:relationships][segment.relationship][:join_type] ||=
82
- segment.relationship.polymorphic? ? default_polymorphic_join_type : default_join_type
83
-
84
- segment.relationship.resource_types.each do |related_resource_type|
85
- related_resource_klass = resource_klass.resource_klass_for(related_resource_type)
86
-
87
- # If the resource type was specified in the path segment we want to only process the next segments for
88
- # that resource type, otherwise process for all
89
- process_all_types = !segment.path_specified_resource_klass?
90
-
91
- if process_all_types || related_resource_klass == segment.resource_klass
92
- related_resource_tree = process_path_to_tree(path_segments.dup, related_resource_klass, default_join_type, default_polymorphic_join_type)
93
- node[:resource_klasses][resource_klass][:relationships][segment.relationship].deep_merge!(related_resource_tree)
94
- end
95
- end
96
- end
97
- node
98
- end
99
-
100
- def parse_path_to_tree(path_string, resource_klass, default_join_type = :inner, default_polymorphic_join_type = :left)
101
- path = JSONAPI::Path.new(resource_klass: resource_klass, path_string: path_string)
102
- field = path.segments[-1]
103
- return process_path_to_tree(path.segments, resource_klass, default_join_type, default_polymorphic_join_type), field
104
- end
105
-
106
- def add_source_relationship(source_relationship)
107
- @source_relationship = source_relationship
108
-
109
- if @source_relationship
110
- resource_klasses = {}
111
- source_relationship.resource_types.each do |related_resource_type|
112
- related_resource_klass = resource_klass.resource_klass_for(related_resource_type)
113
- resource_klasses[related_resource_klass] = {relationships: {}}
114
- end
115
-
116
- join_type = source_relationship.polymorphic? ? :left : :inner
117
-
118
- @resource_joins[:root][:resource_klasses][resource_klass][:relationships][@source_relationship] = {
119
- source: true, resource_klasses: resource_klasses, join_type: join_type
120
- }
121
- end
122
- end
123
-
124
- def add_filters(filters)
125
- return if filters.blank?
126
- filters.each_key do |filter|
127
- # Do not add joins for filters with an apply callable. This can be overridden by setting perform_joins to true
128
- next if resource_klass._allowed_filters[filter].try(:[], :apply) &&
129
- !resource_klass._allowed_filters[filter].try(:[], :perform_joins)
130
-
131
- add_join(filter)
132
- end
133
- end
134
-
135
- def add_sort_criteria(sort_criteria)
136
- return if sort_criteria.blank?
137
-
138
- sort_criteria.each do |sort|
139
- add_join(sort[:field], :left)
140
- end
141
- end
142
-
143
- def add_relationships(relationships)
144
- return if relationships.blank?
145
- relationships.each do |relationship|
146
- add_join(relationship, :left)
147
- end
148
- end
149
-
150
- # Create a nested set of hashes from an array of path components. This will be used by the `join` methods.
151
- # [post, comments] => { post: { comments: {} }
152
- def relation_join_hash(path, path_hash = {})
153
- relation = path.shift
154
- if relation
155
- path_hash[relation] = {}
156
- relation_join_hash(path, path_hash[relation])
157
- end
158
- path_hash
159
- end
160
-
161
- # Returns the paths from shortest to longest, allowing the capture of the table alias for earlier paths. For
162
- # example posts, posts.comments and then posts.comments.author joined in that order will allow each
163
- # alias to be determined whereas just joining posts.comments.author will only record the author alias.
164
- # ToDo: Dependence on this specialized logic should be removed in the future, if possible.
165
- def construct_joins(node, current_relation_path = [], current_relationship_path = [])
166
- node.each do |relationship, relationship_details|
167
- join_type = relationship_details[:join_type]
168
- if relationship == :root
169
- @joins[:root] = {alias: resource_klass._table_name, join_type: :root}
170
-
171
- # alias to the default table unless a source_relationship is specified
172
- unless source_relationship
173
- @joins[''] = {alias: resource_klass._table_name, join_type: :root}
174
- end
175
-
176
- return construct_joins(relationship_details[:resource_klasses].values[0][:relationships],
177
- current_relation_path,
178
- current_relationship_path)
179
- end
180
-
181
- relationship_details[:resource_klasses].each do |resource_klass, resource_details|
182
- if relationship.polymorphic? && relationship.belongs_to?
183
- current_relationship_path << "#{relationship.name.to_s}##{resource_klass._type.to_s}"
184
- relation_name = resource_klass._type.to_s.singularize
185
- else
186
- current_relationship_path << relationship.name.to_s
187
- relation_name = relationship.relation_name(options).to_s
188
- end
189
-
190
- current_relation_path << relation_name
191
-
192
- rel_path = calc_path_string(current_relationship_path)
193
-
194
- @joins[rel_path] = {
195
- alias: nil,
196
- join_type: join_type,
197
- relation_join_hash: relation_join_hash(current_relation_path.dup)
198
- }
199
-
200
- construct_joins(resource_details[:relationships],
201
- current_relation_path.dup,
202
- current_relationship_path.dup)
203
-
204
- current_relation_path.pop
205
- current_relationship_path.pop
206
- end
207
- end
208
- end
209
-
210
- def calc_path_string(path_array)
211
- if source_relationship
212
- if source_relationship.polymorphic?
213
- _relationship_name, resource_name = path_array[0].split('#', 2)
214
- path = path_array.dup
215
- path[0] = "##{resource_name}"
216
- else
217
- path = path_array.dup.drop(1)
218
- end
219
- else
220
- path = path_array.dup
221
- end
222
-
223
- path.join('.')
224
- end
225
- end
226
- end
227
- end