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
@@ -10,6 +10,9 @@ module JSONAPI
|
|
10
10
|
JSONAPI::ActsAsResourceController
|
11
11
|
].compact.freeze
|
12
12
|
|
13
|
+
# Note, the url_helpers are not loaded. This will prevent links from being generated for resources, and warnings
|
14
|
+
# will be emitted. Link support can be added by including `Rails.application.routes.url_helpers`, and links
|
15
|
+
# can be disabled, and warning suppressed, for a resource with `exclude_links :default`
|
13
16
|
MODULES.each do |mod|
|
14
17
|
include mod
|
15
18
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
|
3
|
+
# A ResourceFragment holds a ResourceIdentity and associated partial resource data.
|
4
|
+
#
|
5
|
+
# The following partial resource data may be stored
|
6
|
+
# cache - the value of the cache field for the resource instance
|
7
|
+
# related - a hash of arrays of related resource identities, grouped by relationship name
|
8
|
+
# related_from - a set of related resource identities that loaded the fragment
|
9
|
+
#
|
10
|
+
# Todo: optionally use these for faster responses by bypassing model instantiation)
|
11
|
+
# attributes - resource attributes
|
12
|
+
|
13
|
+
class ResourceFragment
|
14
|
+
attr_reader :identity, :attributes, :related_from, :related
|
15
|
+
|
16
|
+
attr_accessor :primary, :cache
|
17
|
+
|
18
|
+
alias :cache_field :cache #ToDo: Rename one or the other
|
19
|
+
|
20
|
+
def initialize(identity)
|
21
|
+
@identity = identity
|
22
|
+
@cache = nil
|
23
|
+
@attributes = {}
|
24
|
+
@related = {}
|
25
|
+
@primary = false
|
26
|
+
@related_from = Set.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize_related(relationship_name)
|
30
|
+
@related ||= {}
|
31
|
+
@related[relationship_name.to_sym] ||= Set.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_related_identity(relationship_name, identity)
|
35
|
+
initialize_related(relationship_name)
|
36
|
+
@related[relationship_name.to_sym] << identity
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_related_from(identity)
|
40
|
+
@related_from << identity
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_attribute(name, value)
|
44
|
+
@attributes[name] = value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
|
3
|
+
# A tree structure representing the resource structure of the requested resource(s). This is an intermediate structure
|
4
|
+
# used to keep track of the resources, by identity, found at different included relationships. It will be flattened and
|
5
|
+
# the resource instances will be fetched from the cache or the record store.
|
6
|
+
class ResourceIdTree
|
7
|
+
|
8
|
+
attr_reader :fragments, :related_resource_id_trees
|
9
|
+
|
10
|
+
# Gets the related Resource Id Tree for a relationship, and creates it first if it does not exist
|
11
|
+
#
|
12
|
+
# @param relationship [JSONAPI::Relationship]
|
13
|
+
#
|
14
|
+
# @return [JSONAPI::RelatedResourceIdTree] the new or existing resource id tree for the requested relationship
|
15
|
+
def fetch_related_resource_id_tree(relationship)
|
16
|
+
relationship_name = relationship.name.to_sym
|
17
|
+
@related_resource_id_trees[relationship_name] ||= RelatedResourceIdTree.new(relationship, self)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def init_included_relationships(fragment, include_related)
|
23
|
+
include_related && include_related.each_key do |relationship_name|
|
24
|
+
fragment.initialize_related(relationship_name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class PrimaryResourceIdTree < ResourceIdTree
|
30
|
+
|
31
|
+
# Creates a PrimaryResourceIdTree with no resources and no related ResourceIdTrees
|
32
|
+
def initialize
|
33
|
+
@fragments ||= {}
|
34
|
+
@related_resource_id_trees ||= {}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Adds each Resource Fragment to the Resources hash
|
38
|
+
#
|
39
|
+
# @param fragments [Hash]
|
40
|
+
# @param include_related [Hash]
|
41
|
+
#
|
42
|
+
# @return [null]
|
43
|
+
def add_resource_fragments(fragments, include_related)
|
44
|
+
fragments.each_value do |fragment|
|
45
|
+
add_resource_fragment(fragment, include_related)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Adds a Resource Fragment to the Resources hash
|
50
|
+
#
|
51
|
+
# @param fragment [JSONAPI::ResourceFragment]
|
52
|
+
# @param include_related [Hash]
|
53
|
+
#
|
54
|
+
# @return [null]
|
55
|
+
def add_resource_fragment(fragment, include_related)
|
56
|
+
fragment.primary = true
|
57
|
+
|
58
|
+
init_included_relationships(fragment, include_related)
|
59
|
+
|
60
|
+
@fragments[fragment.identity] = fragment
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class RelatedResourceIdTree < ResourceIdTree
|
65
|
+
|
66
|
+
attr_reader :parent_relationship, :source_resource_id_tree
|
67
|
+
|
68
|
+
# Creates a RelatedResourceIdTree with no resources and no related ResourceIdTrees. A connection to the parent
|
69
|
+
# ResourceIdTree is maintained.
|
70
|
+
#
|
71
|
+
# @param parent_relationship [JSONAPI::Relationship]
|
72
|
+
# @param source_resource_id_tree [JSONAPI::ResourceIdTree]
|
73
|
+
#
|
74
|
+
# @return [JSONAPI::RelatedResourceIdTree] the new or existing resource id tree for the requested relationship
|
75
|
+
def initialize(parent_relationship, source_resource_id_tree)
|
76
|
+
@fragments ||= {}
|
77
|
+
@related_resource_id_trees ||= {}
|
78
|
+
|
79
|
+
@parent_relationship = parent_relationship
|
80
|
+
@parent_relationship_name = parent_relationship.name.to_sym
|
81
|
+
@source_resource_id_tree = source_resource_id_tree
|
82
|
+
end
|
83
|
+
|
84
|
+
# Adds each Resource Fragment to the Resources hash
|
85
|
+
#
|
86
|
+
# @param fragments [Hash]
|
87
|
+
# @param include_related [Hash]
|
88
|
+
#
|
89
|
+
# @return [null]
|
90
|
+
def add_resource_fragments(fragments, include_related)
|
91
|
+
fragments.each_value do |fragment|
|
92
|
+
add_resource_fragment(fragment, include_related)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Adds a Resource Fragment to the fragments hash
|
97
|
+
#
|
98
|
+
# @param fragment [JSONAPI::ResourceFragment]
|
99
|
+
# @param include_related [Hash]
|
100
|
+
#
|
101
|
+
# @return [null]
|
102
|
+
def add_resource_fragment(fragment, include_related)
|
103
|
+
init_included_relationships(fragment, include_related)
|
104
|
+
|
105
|
+
fragment.related_from.each do |rid|
|
106
|
+
@source_resource_id_tree.fragments[rid].add_related_identity(parent_relationship.name, fragment.identity)
|
107
|
+
end
|
108
|
+
|
109
|
+
@fragments[fragment.identity] = fragment
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
|
3
|
+
# ResourceIdentity describes a unique identity of a resource in the system.
|
4
|
+
# This consists of a Resource class and an identifier that is unique within
|
5
|
+
# that Resource class. ResourceIdentities are intended to be used as hash
|
6
|
+
# keys to provide ordered mixing of resource types in result sets.
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# == Creating a ResourceIdentity
|
10
|
+
#
|
11
|
+
# rid = ResourceIdentity.new(PostResource, 12)
|
12
|
+
#
|
13
|
+
class ResourceIdentity
|
14
|
+
attr_reader :resource_klass, :id
|
15
|
+
|
16
|
+
def initialize(resource_klass, id)
|
17
|
+
@resource_klass = resource_klass
|
18
|
+
@id = id
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==(other)
|
22
|
+
# :nocov:
|
23
|
+
eql?(other)
|
24
|
+
# :nocov:
|
25
|
+
end
|
26
|
+
|
27
|
+
def eql?(other)
|
28
|
+
other.is_a?(ResourceIdentity) && other.resource_klass == @resource_klass && other.id == @id
|
29
|
+
end
|
30
|
+
|
31
|
+
def hash
|
32
|
+
[@resource_klass, @id].hash
|
33
|
+
end
|
34
|
+
|
35
|
+
# Creates a string representation of the identifier.
|
36
|
+
def to_s
|
37
|
+
# :nocov:
|
38
|
+
"#{resource_klass}:#{id}"
|
39
|
+
# :nocov:
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|