jsonapi-resources 0.9.3 → 0.10.5

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