easy-jsonapi 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/publish-gem.yml +60 -0
- data/.github/workflows/rake.yml +35 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +106 -0
- data/LICENSE.txt +21 -0
- data/README.md +209 -0
- data/Rakefile +20 -0
- data/UsingTheRequestObject.md +74 -0
- data/UsingUserConfigurations.md +95 -0
- data/bin/bundle +114 -0
- data/bin/console +15 -0
- data/bin/htmldiff +29 -0
- data/bin/kramdown +29 -0
- data/bin/ldiff +29 -0
- data/bin/license_finder +29 -0
- data/bin/license_finder_pip.py +29 -0
- data/bin/maruku +29 -0
- data/bin/marutex +29 -0
- data/bin/nokogiri +29 -0
- data/bin/racc +29 -0
- data/bin/rackup +29 -0
- data/bin/rake +29 -0
- data/bin/redcarpet +29 -0
- data/bin/reverse_markdown +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/ruby-parse +29 -0
- data/bin/ruby-rewrite +29 -0
- data/bin/setup +8 -0
- data/bin/solargraph +29 -0
- data/bin/thor +29 -0
- data/bin/tilt +29 -0
- data/bin/yard +29 -0
- data/bin/yardoc +29 -0
- data/bin/yri +29 -0
- data/easy-jsonapi.gemspec +39 -0
- data/lib/easy/jsonapi.rb +12 -0
- data/lib/easy/jsonapi/collection.rb +144 -0
- data/lib/easy/jsonapi/config_manager.rb +144 -0
- data/lib/easy/jsonapi/config_manager/config.rb +49 -0
- data/lib/easy/jsonapi/document.rb +71 -0
- data/lib/easy/jsonapi/document/error.rb +48 -0
- data/lib/easy/jsonapi/document/error/error_member.rb +15 -0
- data/lib/easy/jsonapi/document/jsonapi.rb +26 -0
- data/lib/easy/jsonapi/document/jsonapi/jsonapi_member.rb +15 -0
- data/lib/easy/jsonapi/document/links.rb +36 -0
- data/lib/easy/jsonapi/document/links/link.rb +15 -0
- data/lib/easy/jsonapi/document/meta.rb +26 -0
- data/lib/easy/jsonapi/document/meta/meta_member.rb +14 -0
- data/lib/easy/jsonapi/document/resource.rb +56 -0
- data/lib/easy/jsonapi/document/resource/attributes.rb +37 -0
- data/lib/easy/jsonapi/document/resource/attributes/attribute.rb +29 -0
- data/lib/easy/jsonapi/document/resource/relationships.rb +40 -0
- data/lib/easy/jsonapi/document/resource/relationships/relationship.rb +50 -0
- data/lib/easy/jsonapi/document/resource_id.rb +28 -0
- data/lib/easy/jsonapi/exceptions.rb +27 -0
- data/lib/easy/jsonapi/exceptions/document_exceptions.rb +619 -0
- data/lib/easy/jsonapi/exceptions/headers_exceptions.rb +156 -0
- data/lib/easy/jsonapi/exceptions/naming_exceptions.rb +36 -0
- data/lib/easy/jsonapi/exceptions/query_params_exceptions.rb +67 -0
- data/lib/easy/jsonapi/exceptions/user_defined_exceptions.rb +253 -0
- data/lib/easy/jsonapi/field.rb +43 -0
- data/lib/easy/jsonapi/header_collection.rb +38 -0
- data/lib/easy/jsonapi/header_collection/header.rb +11 -0
- data/lib/easy/jsonapi/item.rb +88 -0
- data/lib/easy/jsonapi/middleware.rb +158 -0
- data/lib/easy/jsonapi/name_value_pair.rb +72 -0
- data/lib/easy/jsonapi/name_value_pair_collection.rb +78 -0
- data/lib/easy/jsonapi/parser.rb +38 -0
- data/lib/easy/jsonapi/parser/document_parser.rb +196 -0
- data/lib/easy/jsonapi/parser/headers_parser.rb +33 -0
- data/lib/easy/jsonapi/parser/rack_req_params_parser.rb +117 -0
- data/lib/easy/jsonapi/request.rb +40 -0
- data/lib/easy/jsonapi/request/query_param_collection.rb +56 -0
- data/lib/easy/jsonapi/request/query_param_collection/fields_param.rb +32 -0
- data/lib/easy/jsonapi/request/query_param_collection/fields_param/fieldset.rb +34 -0
- data/lib/easy/jsonapi/request/query_param_collection/filter_param.rb +28 -0
- data/lib/easy/jsonapi/request/query_param_collection/filter_param/filter.rb +34 -0
- data/lib/easy/jsonapi/request/query_param_collection/include_param.rb +119 -0
- data/lib/easy/jsonapi/request/query_param_collection/page_param.rb +55 -0
- data/lib/easy/jsonapi/request/query_param_collection/query_param.rb +47 -0
- data/lib/easy/jsonapi/request/query_param_collection/sort_param.rb +25 -0
- data/lib/easy/jsonapi/response.rb +22 -0
- data/lib/easy/jsonapi/utility.rb +158 -0
- data/lib/easy/jsonapi/version.rb +8 -0
- metadata +248 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'easy/jsonapi/item'
|
4
|
+
|
5
|
+
module JSONAPI
|
6
|
+
# Field is the name of key value pair
|
7
|
+
class Field < JSONAPI::Item
|
8
|
+
|
9
|
+
# @param name [String] The name of the field
|
10
|
+
# @param type [String | nil] The type of the field
|
11
|
+
def initialize(name, type: String)
|
12
|
+
super({ name: name.to_s, type: type })
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] The Field's name
|
16
|
+
def name
|
17
|
+
@item[:name]
|
18
|
+
end
|
19
|
+
|
20
|
+
# @raise RunTimeError You shoulddn't be able to update the name of a
|
21
|
+
# Resource::Field
|
22
|
+
def name=(_)
|
23
|
+
raise 'Cannot change the name of a Resource::Field'
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Object] The type of the field
|
27
|
+
def type
|
28
|
+
@item[:type]
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param new_type [Object] The new type of field.
|
32
|
+
def type=(new_type)
|
33
|
+
@item[:type] = new_type
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [String] The name of the field.
|
37
|
+
def to_s
|
38
|
+
name
|
39
|
+
end
|
40
|
+
|
41
|
+
private :method_missing, :item, :item=
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'easy/jsonapi/name_value_pair_collection'
|
4
|
+
|
5
|
+
module JSONAPI
|
6
|
+
# header_collection # { include: Include, sort: Sort, filter: Filter }
|
7
|
+
class HeaderCollection < JSONAPI::NameValuePairCollection
|
8
|
+
|
9
|
+
# Initialize as empty if a array of Header objects not passed to it.
|
10
|
+
# @param header_arr [JSONAPI::HeaderCollection::Header] The array of Header objects that can be used to init
|
11
|
+
# a Header collection
|
12
|
+
# @return JSONAPI::HeaderCollection
|
13
|
+
def initialize(header_arr = [])
|
14
|
+
super(header_arr, item_type: JSONAPI::HeaderCollection::Header)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add a header to the collection. (CASE-INSENSITIVE).
|
18
|
+
# @param header [JSONAPI::HeaderCollection::Header] The header to add
|
19
|
+
def add(header)
|
20
|
+
super(header) { |hdr| hdr.name.downcase.gsub(/-/, '_') }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Call super's get but make it case insensitive
|
24
|
+
# @param key [Symbol] The hash key associated with a header
|
25
|
+
def get(key)
|
26
|
+
super(key.to_s.downcase.gsub(/-/, '_'))
|
27
|
+
end
|
28
|
+
|
29
|
+
# #empyt? provided by super
|
30
|
+
# #include provided by super
|
31
|
+
# add provided by super
|
32
|
+
# #each provided from super
|
33
|
+
# #remove provided from super
|
34
|
+
# #keys provided by super
|
35
|
+
# #size provided by super
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
|
5
|
+
# Models a Item's key -> value relationship
|
6
|
+
class Item
|
7
|
+
|
8
|
+
# @return the value of an Item
|
9
|
+
attr_accessor :item
|
10
|
+
|
11
|
+
# Able to take a hash and dynamically create instance variables using the hash keys
|
12
|
+
# Ex: obj == { :name => 'fields', :value => {'articles' => 'title,body,author', 'people' => 'name' }}
|
13
|
+
# @param obj [Object] Can be anything, but if a hash is provided, dynamic instance variable can be created
|
14
|
+
# upon trying to access them.
|
15
|
+
def initialize(obj)
|
16
|
+
if obj.is_a? Hash
|
17
|
+
ensure_keys_are_sym(obj)
|
18
|
+
end
|
19
|
+
@item = obj
|
20
|
+
end
|
21
|
+
|
22
|
+
# A special to_string method if @item is a hash.
|
23
|
+
def to_s
|
24
|
+
return @item.to_s unless @item.is_a? Hash
|
25
|
+
tr = '{ '
|
26
|
+
first = true
|
27
|
+
@item.each do |k, v|
|
28
|
+
if first
|
29
|
+
first = false
|
30
|
+
tr += "\"#{k}\": \"#{v}\", "
|
31
|
+
else
|
32
|
+
tr += "\"#{k}\": \"#{v}\""
|
33
|
+
end
|
34
|
+
end
|
35
|
+
tr += ' }'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Represent item as a hash
|
39
|
+
def to_h
|
40
|
+
@item.to_h
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Only used if implementing Item directly.
|
46
|
+
# dynamically creates accessor methods for instance variables
|
47
|
+
# created in the initialize
|
48
|
+
def method_missing(method_name, *args, &block)
|
49
|
+
return super unless is_a? JSONAPI::Item
|
50
|
+
return super unless @item.is_a? Hash
|
51
|
+
if should_update_var?(method_name)
|
52
|
+
@item[method_name[..-2].to_sym] = args[0]
|
53
|
+
elsif should_get_var?(method_name)
|
54
|
+
@item[method_name]
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Needed when using #method_missing
|
61
|
+
def respond_to_missing?(method_name, *args)
|
62
|
+
instance_variables.include?("@#{method_name}".to_sym) || super
|
63
|
+
end
|
64
|
+
|
65
|
+
# Ensures that hash keys are symbol (and not String) when passing a hash to item.
|
66
|
+
# @param obj [Object] A hash that can represent an item.
|
67
|
+
def ensure_keys_are_sym(obj)
|
68
|
+
obj.each_key do |k|
|
69
|
+
raise "All keys must be Symbols. '#{k}' was #{k.class}" unless k.is_a? Symbol
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Checks to see if the method name has a '=' at the end and if the
|
74
|
+
# prefix before the '=' has the same name as an existing instance
|
75
|
+
# variable.
|
76
|
+
# @param (see #method_missing)
|
77
|
+
def should_update_var?(method_name)
|
78
|
+
method_name.to_s[-1] == '=' && @item[method_name[..-2].to_sym].nil? == false
|
79
|
+
end
|
80
|
+
|
81
|
+
# Checks to see if the method has the same name as an existing instance
|
82
|
+
# variable
|
83
|
+
# @param (see #method_missing)
|
84
|
+
def should_get_var?(method_name)
|
85
|
+
@item[method_name].nil? == false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'easy/jsonapi/exceptions'
|
4
|
+
require 'easy/jsonapi/config_manager'
|
5
|
+
require 'oj'
|
6
|
+
|
7
|
+
module JSONAPI
|
8
|
+
|
9
|
+
# The middleware of the gem and also the contact point between the
|
10
|
+
# the gem and the rack application using it
|
11
|
+
class Middleware
|
12
|
+
# @param app The Rack Application
|
13
|
+
def initialize(app, &block)
|
14
|
+
@app = app
|
15
|
+
return unless block_given?
|
16
|
+
|
17
|
+
@config_manager = JSONAPI::ConfigManager.new
|
18
|
+
block.call(@config_manager)
|
19
|
+
end
|
20
|
+
|
21
|
+
# If not in maintenance_mode and the request is intended to be JSONAPI,
|
22
|
+
# it checks headers, params, and body it for compliance and raises
|
23
|
+
# and error if any section is found to be non-compliant.
|
24
|
+
# @param env The rack envirornment hash
|
25
|
+
def call(env)
|
26
|
+
if in_maintenance_mode?(env)
|
27
|
+
return maintenance_response(env)
|
28
|
+
end
|
29
|
+
|
30
|
+
if jsonapi_request?(env)
|
31
|
+
error_response = check_compliance(env, @config_manager)
|
32
|
+
return error_response unless error_response.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
@app.call(env)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Checks the 'MAINTENANCE' environment variable
|
41
|
+
# @param (see #call)
|
42
|
+
# @return [TrueClass | FalseClass]
|
43
|
+
def in_maintenance_mode?(env)
|
44
|
+
!env['MAINTENANCE'].nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return 503 with or without msg depending on environment
|
48
|
+
# @param (see #call)
|
49
|
+
# @return [Array] Http Error Responses
|
50
|
+
def maintenance_response(env)
|
51
|
+
if environment_development?(env)
|
52
|
+
[503, {}, ['MAINTENANCE envirornment variable set']]
|
53
|
+
else
|
54
|
+
[503, {}, []]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# If the Content-type or Accept header values include the JSON:API media type without media
|
59
|
+
# parameters, then it is a jsonapi request.
|
60
|
+
# @param (see #call)
|
61
|
+
def jsonapi_request?(env)
|
62
|
+
accept_header_jsonapi?(env) || content_type_header_jsonapi?(env)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Determines whether the request is JSONAPI or not by looking at
|
66
|
+
# the ACCEPT header.
|
67
|
+
# @env (see #call)
|
68
|
+
# @return [TrueClass | FalseClass] Whether or not the request is JSONAPI
|
69
|
+
def accept_header_jsonapi?(env)
|
70
|
+
return true if env['HTTP_ACCEPT'].nil? # no header means assume any
|
71
|
+
|
72
|
+
env['HTTP_ACCEPT'].split(',').any? do |hdr|
|
73
|
+
['application/vnd.api+json', '*/*', 'application/*'].include?(hdr.split(';').first)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Determines whether there is a request body, and whether the Content-Type is jsonapi compliant.
|
78
|
+
# @param (see #call)
|
79
|
+
# @return [TrueClass | FalseClass] Whether the document body is supposed to be jsonapi
|
80
|
+
def content_type_header_jsonapi?(env)
|
81
|
+
return false unless env['CONTENT_TYPE']
|
82
|
+
|
83
|
+
env['CONTENT_TYPE'].include? 'application/vnd.api+json'
|
84
|
+
end
|
85
|
+
|
86
|
+
# Checks whether the request is JSON:API compliant and raises an error if not.
|
87
|
+
# @param env (see #call)
|
88
|
+
# @param config_manager [JSONAPI::ConfigManager::Config] The config object to use modify compliance checking
|
89
|
+
# @return [NilClass | Array] Nil meaning no error or a 400 level http response
|
90
|
+
def check_compliance(env, config_manager)
|
91
|
+
opts = { http_method: env['REQUEST_METHOD'], path: env['PATH_INFO'] }
|
92
|
+
|
93
|
+
header_error = check_headers_compliance(env, config_manager, opts)
|
94
|
+
return header_error unless header_error.nil?
|
95
|
+
|
96
|
+
req = Rack::Request.new(env)
|
97
|
+
param_error = check_query_param_compliance(env, req.GET, config_manager, opts)
|
98
|
+
return param_error unless param_error.nil?
|
99
|
+
|
100
|
+
return unless env['CONTENT_TYPE']
|
101
|
+
|
102
|
+
body_error = check_req_body_compliance(env, config_manager, opts)
|
103
|
+
return body_error unless body_error.nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
# Checks whether the http headers are jsonapi compliant
|
107
|
+
# @param (see #call)
|
108
|
+
# @return [NilClass | Array] Nil meaning no error or a 400 level http response
|
109
|
+
def check_headers_compliance(env, config_manager, opts)
|
110
|
+
JSONAPI::Exceptions::HeadersExceptions.check_request(env, config_manager, opts)
|
111
|
+
rescue JSONAPI::Exceptions::HeadersExceptions::InvalidHeader || JSONAPI::Exceptions::UserDefinedExceptions::InvalidHeader => e
|
112
|
+
raise if environment_development?(env)
|
113
|
+
|
114
|
+
[e.status_code, {}, []]
|
115
|
+
end
|
116
|
+
|
117
|
+
# @param query_params [Hash] The rack request query_param hash
|
118
|
+
# @raise If the query parameters are not JSONAPI compliant
|
119
|
+
# @return [NilClass | Array] Nil meaning no error or a 400 level http response
|
120
|
+
def check_query_param_compliance(env, query_params, config_manager, opts)
|
121
|
+
JSONAPI::Exceptions::QueryParamsExceptions.check_compliance(query_params, config_manager, opts)
|
122
|
+
rescue JSONAPI::Exceptions::QueryParamsExceptions::InvalidQueryParameter || JSONAPI::Exceptions::UserDefinedExceptions::InvalidQueryParam => e
|
123
|
+
raise if environment_development?(env)
|
124
|
+
|
125
|
+
[e.status_code, {}, []]
|
126
|
+
end
|
127
|
+
|
128
|
+
# @param env (see #call)
|
129
|
+
# @param req (see #check_query_param_compliance)
|
130
|
+
# @raise If the document body is not JSONAPI compliant
|
131
|
+
def check_req_body_compliance(env, config_manager, opts)
|
132
|
+
# Store separately so you can rewind for next middleware or app
|
133
|
+
body = env['rack.input'].read
|
134
|
+
env['rack.input'].rewind
|
135
|
+
JSONAPI::Exceptions::DocumentExceptions.check_compliance(body, config_manager, opts)
|
136
|
+
rescue JSONAPI::Exceptions::DocumentExceptions::InvalidDocument || JSONAPI::Exceptions::UserDefinedExceptions::InvalidDocument => e
|
137
|
+
raise if environment_development?(env)
|
138
|
+
|
139
|
+
[e.status_code, {}, []]
|
140
|
+
rescue Oj::ParseError
|
141
|
+
raise if environment_development?(env)
|
142
|
+
|
143
|
+
[400, {}, []]
|
144
|
+
end
|
145
|
+
|
146
|
+
# @param (see #call)
|
147
|
+
def post_put_or_patch?(env)
|
148
|
+
env['REQUEST_METHOD'] == 'POST' ||
|
149
|
+
env['REQUEST_METHOD'] == 'PATCH' ||
|
150
|
+
env['REQUEST_METHOD'] == 'PUT'
|
151
|
+
end
|
152
|
+
|
153
|
+
# @param (see #call)
|
154
|
+
def environment_development?(env)
|
155
|
+
env['RACK_ENV'].to_s.downcase == 'development' || env['RACK_ENV'].nil?
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'easy/jsonapi/item'
|
4
|
+
require 'easy/jsonapi/utility'
|
5
|
+
|
6
|
+
module JSONAPI
|
7
|
+
# A generic name->value query pair
|
8
|
+
class NameValuePair < JSONAPI::Item
|
9
|
+
|
10
|
+
# @param name The name of the pair
|
11
|
+
# @param value The value of the pair
|
12
|
+
def initialize(name, value)
|
13
|
+
name = name.to_s.gsub('-', '_')
|
14
|
+
super({ name: name.to_s, value: value })
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [String] The name of the name->val pair
|
18
|
+
def name
|
19
|
+
@item[:name]
|
20
|
+
end
|
21
|
+
|
22
|
+
# @raise RunTimeError You shouldn't be able to update the name of a
|
23
|
+
# NameValuePair
|
24
|
+
def name=(_)
|
25
|
+
raise 'Cannot change the name of NameValuePair Objects'
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String] The value of the name->val pair
|
29
|
+
def value
|
30
|
+
@item[:value]
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param new_value [String | Symbol] The name->val pair value
|
34
|
+
def value=(new_value)
|
35
|
+
@item[:value] = new_value
|
36
|
+
end
|
37
|
+
|
38
|
+
# Represents a pair as a string
|
39
|
+
def to_s
|
40
|
+
v = value
|
41
|
+
val_str = case v
|
42
|
+
when Array
|
43
|
+
val_str = '['
|
44
|
+
first = true
|
45
|
+
v.each do |val|
|
46
|
+
if first
|
47
|
+
val_str += "\"#{val}\""
|
48
|
+
first = false
|
49
|
+
else
|
50
|
+
val_str += ", \"#{val}\""
|
51
|
+
end
|
52
|
+
end
|
53
|
+
val_str += ']'
|
54
|
+
when String
|
55
|
+
"\"#{v}\""
|
56
|
+
when JSONAPI::NameValuePair
|
57
|
+
"{ #{v} }"
|
58
|
+
else
|
59
|
+
v
|
60
|
+
end
|
61
|
+
"\"#{name}\": #{val_str}"
|
62
|
+
end
|
63
|
+
|
64
|
+
# Represents a pair as a hash
|
65
|
+
def to_h
|
66
|
+
{ name.to_sym => JSONAPI::Utility.to_h_value(value) }
|
67
|
+
end
|
68
|
+
|
69
|
+
# prevent users and sublcasses from accessing Parent's #method_missing
|
70
|
+
private :method_missing, :item, :item=
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'easy/jsonapi/collection'
|
4
|
+
require 'easy/jsonapi/name_value_pair'
|
5
|
+
require 'easy/jsonapi/utility'
|
6
|
+
|
7
|
+
module JSONAPI
|
8
|
+
|
9
|
+
# Collection of Items that all have names and values.
|
10
|
+
class NameValuePairCollection < JSONAPI::Collection
|
11
|
+
|
12
|
+
# Creates an empty collection by default
|
13
|
+
# @param pair_arr [Array<JSONAPI::NameValuePair>] The pairs to be initialized with.
|
14
|
+
def initialize(pair_arr = [], item_type: JSONAPI::NameValuePair, &block)
|
15
|
+
if block_given?
|
16
|
+
super(pair_arr, item_type: item_type, &block)
|
17
|
+
else
|
18
|
+
super(pair_arr, item_type: item_type, &:name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# #empyt? provided by super
|
23
|
+
# #include provided by super
|
24
|
+
|
25
|
+
# Add a pair to the collection. (CASE-SENSITIVE)
|
26
|
+
# @param pair [JSONAPI::NameValuePair] The pair to add
|
27
|
+
def add(pair, &block)
|
28
|
+
if block_given?
|
29
|
+
super(pair, &block)
|
30
|
+
else
|
31
|
+
super(pair, &:name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Another way to add a query_param
|
36
|
+
# @oaram (see #add)
|
37
|
+
def <<(pair, &block)
|
38
|
+
add(pair, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
# #each provided from super
|
42
|
+
# #remove provided from super
|
43
|
+
# #get provided by super
|
44
|
+
# #keys provided by super
|
45
|
+
# #size provided by super
|
46
|
+
|
47
|
+
# Represent the collection as a string
|
48
|
+
# @return [String] The representation of the collection
|
49
|
+
def to_s
|
50
|
+
JSONAPI::Utility.to_string_collection(self, pre_string: '{ ', post_string: ' }')
|
51
|
+
end
|
52
|
+
|
53
|
+
# Represent the collection as a hash
|
54
|
+
# @return [Hash] The representation of the collection
|
55
|
+
def to_h
|
56
|
+
JSONAPI::Utility.to_h_collection(self)
|
57
|
+
end
|
58
|
+
|
59
|
+
protected :insert
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
# Gets the NameValuePair object value whose name matches the method_name called
|
64
|
+
# @param method_name [Symbol] The name of the method called
|
65
|
+
# @param args If any arguments were passed to the method called
|
66
|
+
# @param block If a block was passed to the method called
|
67
|
+
def method_missing(method_name, *args, &block)
|
68
|
+
super unless include?(method_name)
|
69
|
+
get(method_name).value
|
70
|
+
end
|
71
|
+
|
72
|
+
# Whether or not method missing should be called.
|
73
|
+
def respond_to_missing?(method_name, *)
|
74
|
+
include?(method_name) || super
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|