easy-jsonapi 1.0.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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/publish-gem.yml +60 -0
  3. data/.github/workflows/rake.yml +35 -0
  4. data/.rspec +3 -0
  5. data/.ruby-version +1 -0
  6. data/CHANGELOG.md +5 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +5 -0
  9. data/Gemfile.lock +106 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +209 -0
  12. data/Rakefile +20 -0
  13. data/UsingTheRequestObject.md +74 -0
  14. data/UsingUserConfigurations.md +95 -0
  15. data/bin/bundle +114 -0
  16. data/bin/console +15 -0
  17. data/bin/htmldiff +29 -0
  18. data/bin/kramdown +29 -0
  19. data/bin/ldiff +29 -0
  20. data/bin/license_finder +29 -0
  21. data/bin/license_finder_pip.py +29 -0
  22. data/bin/maruku +29 -0
  23. data/bin/marutex +29 -0
  24. data/bin/nokogiri +29 -0
  25. data/bin/racc +29 -0
  26. data/bin/rackup +29 -0
  27. data/bin/rake +29 -0
  28. data/bin/redcarpet +29 -0
  29. data/bin/reverse_markdown +29 -0
  30. data/bin/rspec +29 -0
  31. data/bin/rubocop +29 -0
  32. data/bin/ruby-parse +29 -0
  33. data/bin/ruby-rewrite +29 -0
  34. data/bin/setup +8 -0
  35. data/bin/solargraph +29 -0
  36. data/bin/thor +29 -0
  37. data/bin/tilt +29 -0
  38. data/bin/yard +29 -0
  39. data/bin/yardoc +29 -0
  40. data/bin/yri +29 -0
  41. data/easy-jsonapi.gemspec +39 -0
  42. data/lib/easy/jsonapi.rb +12 -0
  43. data/lib/easy/jsonapi/collection.rb +144 -0
  44. data/lib/easy/jsonapi/config_manager.rb +144 -0
  45. data/lib/easy/jsonapi/config_manager/config.rb +49 -0
  46. data/lib/easy/jsonapi/document.rb +71 -0
  47. data/lib/easy/jsonapi/document/error.rb +48 -0
  48. data/lib/easy/jsonapi/document/error/error_member.rb +15 -0
  49. data/lib/easy/jsonapi/document/jsonapi.rb +26 -0
  50. data/lib/easy/jsonapi/document/jsonapi/jsonapi_member.rb +15 -0
  51. data/lib/easy/jsonapi/document/links.rb +36 -0
  52. data/lib/easy/jsonapi/document/links/link.rb +15 -0
  53. data/lib/easy/jsonapi/document/meta.rb +26 -0
  54. data/lib/easy/jsonapi/document/meta/meta_member.rb +14 -0
  55. data/lib/easy/jsonapi/document/resource.rb +56 -0
  56. data/lib/easy/jsonapi/document/resource/attributes.rb +37 -0
  57. data/lib/easy/jsonapi/document/resource/attributes/attribute.rb +29 -0
  58. data/lib/easy/jsonapi/document/resource/relationships.rb +40 -0
  59. data/lib/easy/jsonapi/document/resource/relationships/relationship.rb +50 -0
  60. data/lib/easy/jsonapi/document/resource_id.rb +28 -0
  61. data/lib/easy/jsonapi/exceptions.rb +27 -0
  62. data/lib/easy/jsonapi/exceptions/document_exceptions.rb +619 -0
  63. data/lib/easy/jsonapi/exceptions/headers_exceptions.rb +156 -0
  64. data/lib/easy/jsonapi/exceptions/naming_exceptions.rb +36 -0
  65. data/lib/easy/jsonapi/exceptions/query_params_exceptions.rb +67 -0
  66. data/lib/easy/jsonapi/exceptions/user_defined_exceptions.rb +253 -0
  67. data/lib/easy/jsonapi/field.rb +43 -0
  68. data/lib/easy/jsonapi/header_collection.rb +38 -0
  69. data/lib/easy/jsonapi/header_collection/header.rb +11 -0
  70. data/lib/easy/jsonapi/item.rb +88 -0
  71. data/lib/easy/jsonapi/middleware.rb +158 -0
  72. data/lib/easy/jsonapi/name_value_pair.rb +72 -0
  73. data/lib/easy/jsonapi/name_value_pair_collection.rb +78 -0
  74. data/lib/easy/jsonapi/parser.rb +38 -0
  75. data/lib/easy/jsonapi/parser/document_parser.rb +196 -0
  76. data/lib/easy/jsonapi/parser/headers_parser.rb +33 -0
  77. data/lib/easy/jsonapi/parser/rack_req_params_parser.rb +117 -0
  78. data/lib/easy/jsonapi/request.rb +40 -0
  79. data/lib/easy/jsonapi/request/query_param_collection.rb +56 -0
  80. data/lib/easy/jsonapi/request/query_param_collection/fields_param.rb +32 -0
  81. data/lib/easy/jsonapi/request/query_param_collection/fields_param/fieldset.rb +34 -0
  82. data/lib/easy/jsonapi/request/query_param_collection/filter_param.rb +28 -0
  83. data/lib/easy/jsonapi/request/query_param_collection/filter_param/filter.rb +34 -0
  84. data/lib/easy/jsonapi/request/query_param_collection/include_param.rb +119 -0
  85. data/lib/easy/jsonapi/request/query_param_collection/page_param.rb +55 -0
  86. data/lib/easy/jsonapi/request/query_param_collection/query_param.rb +47 -0
  87. data/lib/easy/jsonapi/request/query_param_collection/sort_param.rb +25 -0
  88. data/lib/easy/jsonapi/response.rb +22 -0
  89. data/lib/easy/jsonapi/utility.rb +158 -0
  90. data/lib/easy/jsonapi/version.rb +8 -0
  91. metadata +248 -0
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'easy/jsonapi/parser/rack_req_params_parser'
4
+ require 'easy/jsonapi/parser/headers_parser'
5
+ require 'easy/jsonapi/parser/document_parser'
6
+ require 'easy/jsonapi/request'
7
+
8
+ require 'rack'
9
+
10
+ module JSONAPI
11
+ # Parsing logic in rack middleware
12
+ module Parser
13
+ # @param env [Hash] The rack envirornment hash
14
+ # @return [JSONAPI::Request] the instantiated jsonapi request object
15
+ def self.parse_request(env)
16
+ req = Rack::Request.new(env)
17
+
18
+ query_param_collection = RackReqParamsParser.parse(req.GET)
19
+ header_collection = HeadersParser.parse(env)
20
+
21
+ req_body = req.body.read # stored separately because can only read 1x
22
+ req.body.rewind # rewind incase something else needs to read the body of the request
23
+ document = includes_jsonapi_document?(env) ? DocumentParser.parse(req_body) : nil
24
+
25
+ JSONAPI::Request.new(env, query_param_collection, header_collection, document)
26
+ end
27
+
28
+ # Is the content type jsonapi?
29
+ # @param (see #parse_request)
30
+ # @return [TrueClass | FalseClass]
31
+ def self.includes_jsonapi_document?(env)
32
+ env['CONTENT_TYPE'] == 'application/vnd.api+json' &&
33
+ env['REQUEST_METHOD'] != 'GET'
34
+ end
35
+
36
+ private_class_method :includes_jsonapi_document?
37
+ end
38
+ end
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'easy/jsonapi/document'
4
+ require 'oj'
5
+
6
+ module JSONAPI
7
+ module Parser
8
+
9
+ # TODO: Only parse valid object members, currenlty parses any included members.
10
+ # Document Parsing Logic
11
+ module DocumentParser
12
+
13
+ # Parse the JSONAPI Request into objects.
14
+ # @param req_body [String] The supplied JSONAPI document with POST, PATCH, PUT, or DELETE.
15
+ # @return [JSONAPI::Document] The parsed JSONAPI document.
16
+ # @raise [JSONAPI::Parser::InvalidDocument] if document is invalid.
17
+ def self.parse(req_body)
18
+ return if req_body.nil?
19
+ document_hash = Oj.load(req_body, symbol_keys: true) # parse json string into hash
20
+ parse_hash(document_hash)
21
+ end
22
+
23
+ # Parse the JSONAPI Request into objects.
24
+ # @param document_hash [Hash] The jsonapi-like ruby hash to parse into objects
25
+ # @return (see #parse)
26
+ # @raise (see #parse)
27
+ def self.parse_hash(document_hash)
28
+ return if document_hash.nil?
29
+ doc_members_hash = parse_top_level_members(document_hash)
30
+ JSONAPI::Document.new(doc_members_hash)
31
+ end
32
+
33
+ # @param document (see #parse!)
34
+ # @return [Hash] A hash containing the objects needed to initialize a
35
+ # JSONAPI::Document
36
+ def self.parse_top_level_members(document)
37
+ doc_members_hash = {}
38
+ doc_members_hash[:data] = parse_resources(document[:data]) if document.key?(:data)
39
+ doc_members_hash[:meta] = parse_meta(document[:meta]) if document.key?(:meta)
40
+ doc_members_hash[:links] = parse_links(document[:links]) if document.key?(:links)
41
+ doc_members_hash[:included] = parse_included(document[:included]) if document.key?(:included)
42
+ doc_members_hash[:errors] = parse_errors(document[:errors]) if document.key?(:errors)
43
+ doc_members_hash[:jsonapi] = parse_jsonapi(document[:jsonapi]) if document.key?(:jsonapi)
44
+ doc_members_hash
45
+ end
46
+
47
+ # @param res_arr [Array<Hash> | Hash] A collection of resources or a resource.
48
+ # @return [JSONAPI::Document::Resource | Array<JSONAPI::Document::Resource>]
49
+ # A resource or collection of resources
50
+ def self.parse_resources(res_arr)
51
+ case res_arr
52
+ when Array
53
+ res_arr.map { |res| parse_resource(res) }
54
+ when Hash
55
+ parse_resource(res_arr)
56
+ else
57
+ raise 'The top level data member must be an array of resources or a resource'
58
+ end
59
+ end
60
+
61
+ # @param res [Hash] The resource hash to parse
62
+ # @return [JSONAPI::Document::Resource] The parsed resource
63
+ def self.parse_resource(res)
64
+ attributes = parse_attributes(res[:attributes]) if res[:attributes]
65
+ relationships = parse_relationships(res[:relationships]) if res[:relationships]
66
+ links = parse_links(res[:links]) if res[:links]
67
+ meta = parse_meta(res[:meta]) if res[:meta]
68
+
69
+ res_members_hash = {
70
+ type: res[:type],
71
+ id: res[:id],
72
+ attributes: attributes,
73
+ relationships: relationships,
74
+ links: links,
75
+ meta: meta
76
+ }
77
+
78
+ JSONAPI::Document::Resource.new(res_members_hash)
79
+ end
80
+
81
+ # @param attrs_hash [Hash] The attributes hash to parse
82
+ # @return [JSONAPI::Document::Resource::Attributes] The parsed attributes
83
+ def self.parse_attributes(attrs_hash)
84
+ attributes = JSONAPI::Document::Resource::Attributes.new
85
+ attrs_hash.each do |name, value|
86
+ cur_attr = JSONAPI::Document::Resource::Attributes::Attribute.new(name, value)
87
+ attributes.add(cur_attr)
88
+ end
89
+ attributes
90
+ end
91
+
92
+ # @param rels_hash [Hash] The relationships hash to parse
93
+ # @return [JSONAPI::Document::Resource::Relationships] The parsed
94
+ # relationships
95
+ def self.parse_relationships(rels_hash)
96
+ relationships = JSONAPI::Document::Resource::Relationships.new
97
+ rels_hash.each do |name, value|
98
+ rel = parse_relationship(name, value)
99
+ relationships.add(rel)
100
+ end
101
+ relationships
102
+ end
103
+
104
+ # @param name [String | Symbol] The name of the relationship being parsed
105
+ # @param rel_hash [Hash] The relationship to parse
106
+ # @return [JSONAPI::Document::Resource::Relationships::Relationship]
107
+ # The parsed relationship
108
+ def self.parse_relationship(name, rel_hash)
109
+ links = parse_links(rel_hash[:links]) if rel_hash[:links]
110
+ data = parse_resource_identifiers(rel_hash[:data]) if rel_hash[:data]
111
+ meta = parse_meta(rel_hash[:meta]) if rel_hash[:meta]
112
+
113
+ rel_members_hash = { name: name, links: links, data: data, meta: meta }
114
+ JSONAPI::Document::Resource::Relationships::Relationship.new(rel_members_hash)
115
+ end
116
+
117
+ # @param links_hash [Hash] The links hash to parse
118
+ # @return [JSONAPI::Document::Links] The parsed links object
119
+ def self.parse_links(links_hash)
120
+ links = JSONAPI::Document::Links.new
121
+ links_hash.each do |name, value|
122
+ cur_link = JSONAPI::Document::Links::Link.new(name, value)
123
+ links.add(cur_link)
124
+ end
125
+ links
126
+ end
127
+
128
+ # @param meta_hash [Hash] The meta hash to parse
129
+ # @return [JSONAPI::Document::Meta] The parsed meta object
130
+ def self.parse_meta(meta_hash)
131
+ meta = JSONAPI::Document::Meta.new
132
+ meta_hash.each do |name, value|
133
+ cur_meta_member = JSONAPI::Document::Meta::MetaMember.new(name, value)
134
+ meta.add(cur_meta_member)
135
+ end
136
+ meta
137
+ end
138
+
139
+ # @param res_id_arr [Hash | Array<Hash>] The resource identifier or
140
+ # array of resource identifiers to parse
141
+ # @return [JSONAPI::Document::ResourceId | Array<JSONAPI::Document::ResourceId]
142
+ # The parsed resource identifier or array or resource identifiers
143
+ def self.parse_resource_identifiers(res_id_arr)
144
+ res_id_hashs = []
145
+ case res_id_arr
146
+ when Array
147
+ res_id_arr.each do |res_id|
148
+ res_id_hashs << parse_resource_identifier(res_id)
149
+ end
150
+ res_id_hashs
151
+ when Hash
152
+ parse_resource_identifier(res_id_arr)
153
+ else
154
+ raise 'Data member of resource relationship was not an array or hash'
155
+ end
156
+ end
157
+
158
+ # @param res_id [Hash] The resource identifier to parse
159
+ # @return [JSONAPI::Document::ResourceId] The parsed resource identifier
160
+ def self.parse_resource_identifier(res_id)
161
+ JSONAPI::Document::ResourceId.new(type: res_id[:type], id: res_id[:id])
162
+ end
163
+
164
+ # @param included_arr [Array<Hash>] The array of included resoures to parse
165
+ # @return [Array<JSONAPI::Document::Resource] The array of parsed included resources
166
+ def self.parse_included(included_arr)
167
+ res_arr = []
168
+ included_arr.each do |res|
169
+ res_arr << parse_resource(res)
170
+ end
171
+ res_arr
172
+ end
173
+
174
+ # @param errs_arr [Array<Hash>] The array of errors to parse
175
+ # @return [Array<JSONAPI::Document::Error>] The parsed error objects
176
+ def self.parse_errors(errs_arr)
177
+ errs_hash_arr = []
178
+ errs_arr.each do |err_hash|
179
+ errs_hash_arr << parse_error(err_hash)
180
+ end
181
+ errs_hash_arr
182
+ end
183
+
184
+ # @param err_hash [Hash] The error hash to parse
185
+ # @return [JSONAPI::Document::Error] The parsed error object
186
+ def self.parse_error(err_hash)
187
+ error = JSONAPI::Document::Error.new
188
+ err_hash.each do |name, value|
189
+ error.add(JSONAPI::Document::Error::ErrorMember.new(name, value))
190
+ end
191
+ error
192
+ end
193
+
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'easy/jsonapi/collection'
4
+ require 'easy/jsonapi/header_collection'
5
+
6
+ require 'easy/jsonapi/item'
7
+ require 'easy/jsonapi/header_collection/header'
8
+
9
+ require 'easy/jsonapi/exceptions/headers_exceptions'
10
+
11
+ module JSONAPI
12
+ module Parser
13
+
14
+ # Header parsing logic
15
+ module HeadersParser
16
+
17
+ # @param env [Hash] The rack envirornment hash
18
+ # @return [JSONAPI::HeaderCollection] The collection of parsed header objects
19
+ def self.parse(env)
20
+ h_collection = JSONAPI::HeaderCollection.new
21
+ env.each_key do |k|
22
+ if k.start_with?('HTTP_') && (k != 'HTTP_VERSION')
23
+ h_collection << JSONAPI::HeaderCollection::Header.new(k[5..], env[k])
24
+ elsif k == 'CONTENT_TYPE'
25
+ h_collection << JSONAPI::HeaderCollection::Header.new(k, env[k])
26
+ end
27
+ end
28
+ h_collection
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'easy/jsonapi/exceptions/query_params_exceptions'
4
+
5
+ require 'easy/jsonapi/request/query_param_collection'
6
+
7
+ require 'easy/jsonapi/request/query_param_collection/query_param'
8
+
9
+ require 'easy/jsonapi/request/query_param_collection/filter_param'
10
+ require 'easy/jsonapi/request/query_param_collection/filter_param/filter'
11
+
12
+ require 'easy/jsonapi/request/query_param_collection/include_param'
13
+ require 'easy/jsonapi/request/query_param_collection/page_param'
14
+ require 'easy/jsonapi/request/query_param_collection/sort_param'
15
+
16
+ require 'easy/jsonapi/request/query_param_collection/fields_param'
17
+ require 'easy/jsonapi/request/query_param_collection/fields_param/fieldset'
18
+
19
+ require 'easy/jsonapi/field'
20
+
21
+ module JSONAPI
22
+ module Parser
23
+
24
+ # Used to parse the request params given from the Rack::Request object
25
+ module RackReqParamsParser
26
+
27
+ # @param rack_req_params [Hash<String>] The parameter hash returned from Rack::Request.params
28
+ # @return [JSONAPI::Request::QueryParamCollection]
29
+ def self.parse(rack_req_params)
30
+
31
+ # rack::request.params: (string keys)
32
+ # {
33
+ # 'fields' => { 'articles' => 'title,body,author', 'people' => 'name' },
34
+ # 'include' => 'author,comments-likers,comments.users',
35
+ # 'josh_ua' => 'demoss,simpson',
36
+ # 'page' => { 'offset' => '5', 'limit' => '20' },
37
+ # 'filter' => { 'comments' => '(author/age > 21)', 'users' => '(age < 15)' },
38
+ # 'sort' => 'age,title'
39
+ # }
40
+
41
+ query_param_collection = JSONAPI::Request::QueryParamCollection.new
42
+ rack_req_params.each do |name, value|
43
+ add_the_param(name, value, query_param_collection)
44
+ end
45
+ query_param_collection
46
+ end
47
+
48
+ class << self
49
+ private
50
+
51
+ # @param name [String] The name of the query param to add
52
+ # @param value [String | Hash] The value of the query param to add
53
+ # @param query_param_collection [JSONAPI::Request::QueryParamCollection]
54
+ # The collection to add all the params to
55
+ def add_the_param(name, value, query_param_collection)
56
+ case name
57
+ when 'include'
58
+ query_param_collection.add(parse_include_param(value))
59
+ when 'fields'
60
+ query_param_collection.add(parse_fields_param(value))
61
+ when 'sort'
62
+ query_param_collection.add(parse_sort_param(value))
63
+ when 'page'
64
+ query_param_collection.add(parse_page_param(value))
65
+ when 'filter'
66
+ query_param_collection.add(parse_filter_param(value))
67
+ else
68
+ query_param_collection.add(parse_query_param(name, value))
69
+ end
70
+ end
71
+
72
+ # @param value [String] The value to initialize with
73
+ def parse_include_param(value)
74
+ includes_arr = value.split(',')
75
+ JSONAPI::Request::QueryParamCollection::IncludeParam.new(includes_arr)
76
+ end
77
+
78
+ # @param (see #parse_include_param)
79
+ def parse_fields_param(value)
80
+ fieldsets = []
81
+ value.each do |res_type, res_field_str|
82
+ res_field_str_arr = res_field_str.split(',')
83
+ res_field_arr = res_field_str_arr.map { |res_field| JSONAPI::Field.new(res_field) }
84
+ fieldsets << JSONAPI::Request::QueryParamCollection::FieldsParam::Fieldset.new(res_type, res_field_arr)
85
+ end
86
+ JSONAPI::Request::QueryParamCollection::FieldsParam.new(fieldsets)
87
+ end
88
+
89
+ # @param (see #parse_include_param)
90
+ def parse_sort_param(value)
91
+ res_field_arr = value.split(',').map { |res_field| JSONAPI::Field.new(res_field) }
92
+ JSONAPI::Request::QueryParamCollection::SortParam.new(res_field_arr)
93
+ end
94
+
95
+ # @param (see #parse_include_param)
96
+ def parse_page_param(value)
97
+ JSONAPI::Request::QueryParamCollection::PageParam.new(offset: value[:offset], limit: value[:limit])
98
+ end
99
+
100
+ # @param (see #parse_include_param)
101
+ def parse_filter_param(value)
102
+
103
+ filter_arr = value.map do |res_name, filter|
104
+ JSONAPI::Request::QueryParamCollection::FilterParam::Filter.new(res_name, filter)
105
+ end
106
+ JSONAPI::Request::QueryParamCollection::FilterParam.new(filter_arr)
107
+ end
108
+
109
+ # @param (see #parse_include_param)
110
+ def parse_query_param(name, value)
111
+ JSONAPI::Request::QueryParamCollection::QueryParam.new(name, value)
112
+ end
113
+
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPI
4
+ # Contains all objects relating to a HTTP request
5
+ class Request
6
+ attr_reader :path, :http_method, :host, :port, :query_string, :params, :headers, :body
7
+
8
+ # @param env The rack envirornment hash
9
+ # @param query_param_collection [QueryParamCollection] The already initialized QueryParamCollection class
10
+ # @param header_collection [HeaderCollection] The already initialized HeaderCollection class
11
+ # @param document [Document] The already initialized Document class
12
+ def initialize(env, query_param_collection, header_collection, document)
13
+ # from env hash
14
+ @path = env['REQUEST_PATH']
15
+ @http_method = env['REQUEST_METHOD']
16
+ @host = env['SERVER_NAME']
17
+ @port = env['SERVER_PORT'].to_i
18
+ @query_string = env['QUERY_STRING']
19
+
20
+ # parsed objects
21
+ @params = query_param_collection
22
+ @headers = header_collection
23
+ @body = document
24
+ end
25
+
26
+ # Simple representation of a request object.
27
+ def to_s
28
+ "Quick Access Methods:\n\n" \
29
+ "\tpath: #{@path}\n" \
30
+ "\thttp: #{@http}\n" \
31
+ "\thost: #{@host}\n" \
32
+ "\tport: #{@port}\n" \
33
+ "\tquery_string: #{@query_string}\n\n" \
34
+ "Accessing main sections of request:\n\n" \
35
+ "\tparams: #{@params}\n" \
36
+ "\theaders: #{@headers}\n" \
37
+ "\tbody: #{@body}" \
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'easy/jsonapi/name_value_pair_collection'
4
+ require 'easy/jsonapi/utility'
5
+
6
+ module JSONAPI
7
+ class Request
8
+ # A collection of QueryParam objects
9
+ class QueryParamCollection < JSONAPI::NameValuePairCollection
10
+
11
+ # @param param_arr [Array<JSONAPI::Request::QueryParamCollection::QueryParam] The
12
+ # query params to initialize the collection with
13
+ def initialize(param_arr = [])
14
+ @param_names = []
15
+ super(param_arr, item_type: JSONAPI::Request::QueryParamCollection::QueryParam)
16
+ end
17
+
18
+ # #empyt? provided by super class
19
+ # #include provided by super class
20
+
21
+ # Add a QueryParameter to the collection. (CASE-SENSITIVE)
22
+ # @param param [JSONAPI::Request::QueryParamCollection::QueryParam] The param to add
23
+ def add(param)
24
+ super(param, &:name)
25
+ end
26
+
27
+ # #<< provided by super, but calls overriden #add
28
+ # #each provided from super
29
+ # #remove provided from super
30
+ # #get provided by super
31
+ # #keys provided by super
32
+ # #size provided by super
33
+
34
+ # Represent query param collection like the query_param string
35
+ def to_s
36
+ JSONAPI::Utility.to_string_collection(self, delimiter: '&')
37
+ end
38
+
39
+ private
40
+
41
+ # Gets the QueryParam object whose name matches the method_name called
42
+ # @param method_name [Symbol] The name of the method called
43
+ # @param args If any arguments were passed to the method called
44
+ # @param block If a block was passed to the method called
45
+ def method_missing(method_name, *args, &block)
46
+ super unless include?(method_name)
47
+ get(method_name)
48
+ end
49
+
50
+ # Whether or not method missing should be called.
51
+ def respond_to_missing?(method_name, *)
52
+ include?(method_name) || super
53
+ end
54
+ end
55
+ end
56
+ end