jsonapi-resources 0.9.11 → 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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +34 -11
  4. data/lib/bug_report_templates/rails_5_latest.rb +125 -0
  5. data/lib/bug_report_templates/rails_5_master.rb +140 -0
  6. data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +27 -0
  7. data/lib/jsonapi/active_relation/join_manager.rb +303 -0
  8. data/lib/jsonapi/active_relation_resource.rb +884 -0
  9. data/lib/jsonapi/acts_as_resource_controller.rb +122 -106
  10. data/lib/jsonapi/basic_resource.rb +1162 -0
  11. data/lib/jsonapi/cached_response_fragment.rb +127 -0
  12. data/lib/jsonapi/compiled_json.rb +11 -1
  13. data/lib/jsonapi/configuration.rb +57 -8
  14. data/lib/jsonapi/error.rb +27 -0
  15. data/lib/jsonapi/error_codes.rb +2 -0
  16. data/lib/jsonapi/exceptions.rb +63 -40
  17. data/lib/jsonapi/formatter.rb +3 -3
  18. data/lib/jsonapi/include_directives.rb +18 -75
  19. data/lib/jsonapi/link_builder.rb +16 -19
  20. data/lib/jsonapi/operation.rb +16 -5
  21. data/lib/jsonapi/operation_result.rb +73 -15
  22. data/lib/jsonapi/paginator.rb +17 -0
  23. data/lib/jsonapi/path.rb +43 -0
  24. data/lib/jsonapi/path_segment.rb +76 -0
  25. data/lib/jsonapi/processor.rb +246 -111
  26. data/lib/jsonapi/relationship.rb +117 -18
  27. data/lib/jsonapi/request_parser.rb +383 -396
  28. data/lib/jsonapi/resource.rb +3 -1376
  29. data/lib/jsonapi/resource_controller_metal.rb +5 -2
  30. data/lib/jsonapi/resource_fragment.rb +47 -0
  31. data/lib/jsonapi/resource_id_tree.rb +112 -0
  32. data/lib/jsonapi/resource_identity.rb +42 -0
  33. data/lib/jsonapi/resource_serializer.rb +124 -286
  34. data/lib/jsonapi/resource_set.rb +176 -0
  35. data/lib/jsonapi/resources/railtie.rb +9 -0
  36. data/lib/jsonapi/resources/version.rb +1 -1
  37. data/lib/jsonapi/response_document.rb +104 -87
  38. data/lib/jsonapi/routing_ext.rb +19 -21
  39. data/lib/jsonapi-resources.rb +20 -4
  40. data/lib/tasks/check_upgrade.rake +52 -0
  41. metadata +36 -33
  42. data/lib/jsonapi/cached_resource_fragment.rb +0 -127
  43. data/lib/jsonapi/operation_dispatcher.rb +0 -88
  44. data/lib/jsonapi/operation_results.rb +0 -35
  45. data/lib/jsonapi/relationship_builder.rb +0 -167
@@ -1,8 +1,11 @@
1
1
  module JSONAPI
2
2
  class Relationship
3
3
  attr_reader :acts_as_set, :foreign_key, :options, :name,
4
- :class_name, :polymorphic, :always_include_linkage_data,
5
- :parent_resource, :eager_load_on_include
4
+ :class_name, :polymorphic, :always_include_optional_linkage_data,
5
+ :parent_resource, :eager_load_on_include, :custom_methods,
6
+ :inverse_relationship, :allow_include, :use_related_resource_records_for_joins
7
+
8
+ attr_writer :allow_include
6
9
 
7
10
  attr_accessor :_routed, :_warned_missing_route
8
11
 
@@ -14,26 +17,75 @@ module JSONAPI
14
17
  @parent_resource = options[:parent_resource]
15
18
  @relation_name = options.fetch(:relation_name, @name)
16
19
  @polymorphic = options.fetch(:polymorphic, false) == true
17
- @always_include_linkage_data = options.fetch(:always_include_linkage_data, false) == true
18
- @eager_load_on_include = options.fetch(:eager_load_on_include, true) == true
20
+ @polymorphic_types = options[:polymorphic_types]
21
+ if options[:polymorphic_relations]
22
+ ActiveSupport::Deprecation.warn('Use polymorphic_types instead of polymorphic_relations')
23
+ @polymorphic_types ||= options[:polymorphic_relations]
24
+ end
25
+
26
+ use_related_resource_records_for_joins_default = if options[:relation_name]
27
+ false
28
+ else
29
+ JSONAPI.configuration.use_related_resource_records_for_joins
30
+ end
31
+
32
+ @use_related_resource_records_for_joins = options.fetch(:use_related_resource_records_for_joins,
33
+ use_related_resource_records_for_joins_default) == true
34
+
35
+ @always_include_optional_linkage_data = options.fetch(:always_include_optional_linkage_data, false) == true
36
+ @eager_load_on_include = options.fetch(:eager_load_on_include, false) == true
37
+ @allow_include = options[:allow_include]
38
+ @class_name = nil
39
+ @inverse_relationship = nil
40
+
19
41
  @_routed = false
20
42
  @_warned_missing_route = false
21
43
 
22
44
  exclude_links(options.fetch(:exclude_links, JSONAPI.configuration.default_exclude_links))
45
+
46
+ # Custom methods are reserved for future use
47
+ @custom_methods = options.fetch(:custom_methods, {})
23
48
  end
24
49
 
25
50
  alias_method :polymorphic?, :polymorphic
51
+ alias_method :parent_resource_klass, :parent_resource
26
52
 
27
53
  def primary_key
54
+ # :nocov:
28
55
  @primary_key ||= resource_klass._primary_key
56
+ # :nocov:
29
57
  end
30
58
 
31
59
  def resource_klass
32
- @resource_klass ||= @parent_resource.resource_for(@class_name)
60
+ @resource_klass ||= @parent_resource.resource_klass_for(@class_name)
33
61
  end
34
62
 
35
63
  def table_name
64
+ # :nocov:
36
65
  @table_name ||= resource_klass._table_name
66
+ # :nocov:
67
+ end
68
+
69
+ def self.polymorphic_types(name)
70
+ @poly_hash ||= {}.tap do |hash|
71
+ ObjectSpace.each_object do |klass|
72
+ next unless Module === klass
73
+ if ActiveRecord::Base > klass
74
+ klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
75
+ (hash[reflection.options[:as]] ||= []) << klass.name.underscore
76
+ end
77
+ end
78
+ end
79
+ end
80
+ @poly_hash[name.to_sym]
81
+ end
82
+
83
+ def resource_types
84
+ if polymorphic? && belongs_to?
85
+ @polymorphic_types ||= self.class.polymorphic_types(@relation_name).collect {|t| t.pluralize}
86
+ else
87
+ [resource_klass._type.to_s.pluralize]
88
+ end
37
89
  end
38
90
 
39
91
  def type
@@ -53,17 +105,14 @@ module JSONAPI
53
105
  end
54
106
  end
55
107
 
56
- def type_for_source(source)
57
- if polymorphic?
58
- resource = source.public_send(name)
59
- resource.class._type if resource
60
- else
61
- type
62
- end
63
- end
64
-
65
108
  def belongs_to?
109
+ # :nocov:
66
110
  false
111
+ # :nocov:
112
+ end
113
+
114
+ def readonly?
115
+ @options[:readonly]
67
116
  end
68
117
 
69
118
  def exclude_links(exclude)
@@ -95,39 +144,89 @@ module JSONAPI
95
144
  @class_name = options.fetch(:class_name, name.to_s.camelize)
96
145
  @foreign_key ||= "#{name}_id".to_sym
97
146
  @foreign_key_on = options.fetch(:foreign_key_on, :self)
147
+ if parent_resource
148
+ @inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type)
149
+ end
98
150
  end
99
151
 
100
152
  def to_s
101
- # :nocov:
153
+ # :nocov: useful for debugging
102
154
  "#{parent_resource}.#{name}(#{belongs_to? ? 'BelongsToOne' : 'ToOne'})"
103
155
  # :nocov:
104
156
  end
105
157
 
106
158
  def belongs_to?
159
+ # :nocov:
107
160
  foreign_key_on == :self
161
+ # :nocov:
108
162
  end
109
163
 
110
164
  def polymorphic_type
111
165
  "#{name}_type" if polymorphic?
112
166
  end
167
+
168
+ def include_optional_linkage_data?
169
+ @always_include_optional_linkage_data || JSONAPI::configuration.always_include_to_one_linkage_data
170
+ end
171
+
172
+ def allow_include?(context = nil)
173
+ strategy = if @allow_include.nil?
174
+ JSONAPI.configuration.default_allow_include_to_one
175
+ else
176
+ @allow_include
177
+ end
178
+
179
+ if !!strategy == strategy #check for boolean
180
+ return strategy
181
+ elsif strategy.is_a?(Symbol) || strategy.is_a?(String)
182
+ parent_resource.send(strategy, context)
183
+ else
184
+ strategy.call(context)
185
+ end
186
+ end
113
187
  end
114
188
 
115
189
  class ToMany < Relationship
116
- attr_reader :reflect, :inverse_relationship
190
+ attr_reader :reflect
117
191
 
118
192
  def initialize(name, options = {})
119
193
  super
120
194
  @class_name = options.fetch(:class_name, name.to_s.camelize.singularize)
121
195
  @foreign_key ||= "#{name.to_s.singularize}_ids".to_sym
122
196
  @reflect = options.fetch(:reflect, true) == true
123
- @inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type.to_s.singularize.to_sym) if parent_resource
197
+ if parent_resource
198
+ @inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type.to_s.singularize.to_sym)
199
+ end
124
200
  end
125
201
 
126
202
  def to_s
127
- # :nocov:
203
+ # :nocov: useful for debugging
128
204
  "#{parent_resource}.#{name}(ToMany)"
129
205
  # :nocov:
130
206
  end
207
+
208
+ def include_optional_linkage_data?
209
+ # :nocov:
210
+ @always_include_optional_linkage_data || JSONAPI::configuration.always_include_to_many_linkage_data
211
+ # :nocov:
212
+ end
213
+
214
+ def allow_include?(context = nil)
215
+ strategy = if @allow_include.nil?
216
+ JSONAPI.configuration.default_allow_include_to_many
217
+ else
218
+ @allow_include
219
+ end
220
+
221
+ if !!strategy == strategy #check for boolean
222
+ return strategy
223
+ elsif strategy.is_a?(Symbol) || strategy.is_a?(String)
224
+ parent_resource.send(strategy, context)
225
+ else
226
+ strategy.call(context)
227
+ end
228
+ end
229
+
131
230
  end
132
231
  end
133
232
  end