Module: JSONAPI::Exceptions::DocumentExceptions

Defined in:
lib/easy/jsonapi/exceptions.rb,
lib/easy/jsonapi/exceptions/document_exceptions.rb

Overview

Validates that the request or response document complies with the JSONAPI specification

Defined Under Namespace

Classes: InvalidDocument

Constant Summary collapse

REQUIRED_TOP_LEVEL_KEYS =

A jsonapi document MUST contain at least one of the following top-level members

%i[data errors meta].freeze
%i[self related first prev next last].freeze
%i[first prev next last].freeze
%i[href meta].freeze
RESOURCE_KEYS =

A resource object MUST contain at least id and type (unless a post resource)

In addition, a resource object MAY contain these top-level members.
%i[type id attributes relationships links meta].freeze
RELATIONSHIP_KEYS =

A relationships object MUST contain one of the following:

%i[data links meta].freeze
%i[self related].freeze
RESOURCE_IDENTIFIER_KEYS =

Every resource object MUST contain an id member and a type member.

%i[type id].freeze

Class Method Summary collapse

Class Method Details

.any_additional_includes?(possible_includes, actual_includes) ⇒ Boolean

Parameters:

  • possible_includes (Hash)

    The collection of possible includes

  • actual_includes (Hash)

    The included top level object

Returns:

  • (Boolean)


568
569
570
571
572
573
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 568

def any_additional_includes?(possible_includes, actual_includes)
  actual_includes.each do |res|
    return false unless possible_includes.key? res_id_to_sym(res[:type], res[:id])
  end
  true
end

.check_attributes(attributes) ⇒ Object

Parameters:

  • attributes (Hash)

    The attributes for resource



199
200
201
202
203
204
205
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 199

def check_attributes(attributes)
  ensure!(attributes.is_a?(Hash),
          'The value of the attributes key MUST be an object')
  # Attribute members can contain any json value (verified using OJ JSON parser), but
  #   must not contain any attribute or links member -- see #check_full_linkage for this check
  # Member names checked separately.
end

.check_compliance(document, config_manager = nil, opts = {}) ⇒ Object

Checks a request document against the JSON:API spec to see if it complies

Parameters:

  • document (String | Hash)

    The jsonapi document included with the http request

  • opts (Hash) (defaults to: {})

    Includes path, http_method, sparse_fieldsets

Raises:

  • InvalidDocument if any part of the spec is not observed



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 60

def self.check_compliance(document, config_manager = nil, opts = {})
  document = JSONAPI::Parser::JSONParser.parse(document) if document.is_a? String
  ensure!(!document.nil?, 'A document cannot be nil')
  
  check_essentials(document, opts[:http_method])
  check_members(document, opts[:http_method], opts[:path], opts[:sparse_fieldsets])
  check_for_matching_types(document, opts[:http_method], opts[:path])
  check_member_names(document)
  
  usr_opts = { http_method: opts[:http_method], path: opts[:path] }
  err = JSONAPI::Exceptions::UserDefinedExceptions.check_user_document_requirements(document, config_manager, usr_opts)
  raise err unless err.nil?
  
  nil
end

.check_data(data, http_method, path) ⇒ Object

Parameters:

  • data (Hash | Array<Hash>)

    A resource or array or resources



145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 145

def check_data(data, http_method, path)
  ensure!(data.is_a?(Hash) || http_method.nil? || clearing_relationship_link?(data, http_method, path),
          'The request MUST include a single resource object as primary data, ' \
          'unless it is a PATCH request clearing a relationship using a relationship link')
  case data
  when Hash
    check_resource(data, http_method)
  when Array
    data.each { |res| check_resource(res, http_method) }
  else
    ensure!(data.nil?,
            'Primary data must be either nil, an object or an array')
  end
end

.check_error(error) ⇒ Object

Parameters:

  • error (Hash)

    The individual error object

Raises:

  • InvalidDocument if any part of the spec is not observed



385
386
387
388
389
390
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 385

def check_error(error)
  ensure!(error.is_a?(Hash),
          'Error objects MUST be objects')
  check_links(error[:links]) if error.key? :links
  check_links(error[:meta]) if error.key? :meta
end

.check_errors(errors) ⇒ Object

Parameters:

  • errors (Array)

    The array of errors contained in the jsonapi document



377
378
379
380
381
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 377

def check_errors(errors)
  ensure!(errors.is_a?(Array),
          'Top level errors member MUST be an array')
  errors.each { |error| check_error(error) }
end

.check_essentials(document, http_method) ⇒ Object

Checks the essentials of a jsonapi document. It is

used by #check_compliance and JSONAPI::Document's #initialize method


82
83
84
85
86
87
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 82

def check_essentials(document, http_method)
  ensure!(document.is_a?(Hash),
          'A JSON object MUST be at the root of every JSON API request ' \
          'and response containing data')  
  check_top_level(document, http_method)
end

.check_for_matching_types(document, http_method, path) ⇒ Object

Raises a 409 error if the endpoint type does not match the data type on a post request

Parameters:

  • http_method (String)

    The request request method

  • path (String)

    The request path



442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 442

def check_for_matching_types(document, http_method, path)
  return unless http_method
  return unless path
  
  return unless JSONAPI::Utility.all_hash_path?(document, %i[data type])
  
  res_type = document[:data][:type]
  case http_method
  when 'POST'
    path_type = path.split('/')[-1]
    check_post_type(path_type, res_type)
  when 'PATCH'
    temp = path.split('/')
    path_type = temp[-2]
    path_id = temp[-1]
    res_id = document.dig(:data, :id)
    check_patch_type(path_type, res_type, path_id, res_id)
  end
end

.check_full_linkage(document, http_method) ⇒ Object

Checking if document is fully linked

Parameters:

  • document (Hash)

    The jsonapi document



397
398
399
400
401
402
403
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 397

def check_full_linkage(document, http_method)
  return if http_method
  
  ensure!(full_linkage?(document),
          'Compound documents require “full linkage”, meaning that every included resource MUST be ' \
          'identified by at least one resource identifier object in the same document.')
end

.check_included(included) ⇒ Object

Parameters:

  • included (Array)

    The array of included resources



272
273
274
275
276
277
278
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 272

def check_included(included)
  ensure!(included.is_a?(Array),
          'The top level included member MUST be represented as an array of resource objects')
  
  check_included_resources(included)
  # Full linkage check is in #check_members
end

.check_included_resources(included) ⇒ Object

Check each included resource for compliance and make sure each type/id pair is unique



283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 283

def check_included_resources(included)
  no_duplicate_type_and_id_pairs = true
  set = {}
  included.each do |res|
    check_resource(res)
    unless unique_pair?(set, res)
      no_duplicate_type_and_id_pairs = false
      break
    end
  end
  ensure!(no_duplicate_type_and_id_pairs,
          'A compound document MUST NOT include more ' \
          'than one resource object for each type and id pair.')
end

.check_individual_members(document, http_method, path) ⇒ Object

Checks individual members of the jsonapi document for errors



130
131
132
133
134
135
136
137
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 130

def check_individual_members(document, http_method, path)
  check_data(document[:data], http_method, path) if document.key? :data
  check_included(document[:included]) if document.key? :included
  check_meta(document[:meta]) if document.key? :meta
  check_errors(document[:errors]) if document.key? :errors
  check_jsonapi(document[:jsonapi]) if document.key? :jsonapi
  check_links(document[:links]) if document.key? :links
end

.check_jsonapi(jsonapi) ⇒ Object

Parameters:

  • jsonapi (Hash)

    The top level jsonapi object

Raises:

  • InvalidDocument if any part of the spec is not observed



364
365
366
367
368
369
370
371
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 364

def check_jsonapi(jsonapi)
  ensure!(jsonapi.is_a?(Hash), 'A JSONAPI object MUST be an object')
  if jsonapi.key?(:version)
    ensure!(jsonapi[:version].is_a?(String),
            "The value of JSONAPI's version member MUST be a string")
  end
  check_meta(jsonapi[:meta]) if jsonapi.key?(:meta)
end

Parameters:

  • link (String | Hash)

    A member of the links object

Raises:

  • InvalidDocument if any part of the spec is not observed



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 342

def check_link(link)
  # A link MUST be either a string URL or an object with href / meta
  case link
  when String
    # Do nothing
  when Hash
    ensure!((link.keys - LINK_KEYS).empty?,
            'If the link is an object, it can contain the members href or meta')
    ensure!(link[:href].nil? || link[:href].instance_of?(String),
            'The member href MUST be a string')
    ensure!(link[:meta].nil? || link[:meta].instance_of?(Hash),
            'The value of each meta member MUST be an object')
  else
    ensure!(false,
            'A link MUST be represented as either a string or an object')
  end
end

Parameters:

  • links (Hash)

    The links object

Raises:

  • InvalidDocument if any part of the spec is not observed



334
335
336
337
338
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 334

def check_links(links)
  ensure!(links.is_a?(Hash), 'A links object MUST be an object')
  links.each_value { |link| check_link(link) }
  nil
end

.check_member_names(obj) ⇒ Object

Checks all the member names in a document recursively and raises an error saying

which member did not observe the jsonapi member name rules and which rule

Parameters:

  • obj

    The entire request document or part of the request document.



413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 413

def check_member_names(obj)
  case obj
  when Hash
    obj.each do |k, v| 
      check_name(k)
      check_member_names(v)
    end
  when Array
    obj.each { |hsh| check_member_names(hsh) }
  end
  nil
end

.check_members(document, http_method, path, sparse_fieldsets) ⇒ Object

Checks if any errors exist in the jsonapi document members

Parameters:

  • http_method (String)

    The http verb

  • sparse_fieldsets (TrueClass | FalseClass | Nilclass)


122
123
124
125
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 122

def check_members(document, http_method, path, sparse_fieldsets)
  check_individual_members(document, http_method, path)
  check_full_linkage(document, http_method) unless sparse_fieldsets && http_method.nil?
end

.check_meta(meta) ⇒ Object

Parameters:

  • meta (Hash)

    The meta object

Raises:

  • InvalidDocument if any part of the spec is not observed



315
316
317
318
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 315

def check_meta(meta)
  ensure!(meta.is_a?(Hash), 'A meta object MUST be an object')
  # Any members may be specified in a meta obj (all members will be valid json bc string is parsed by oj)
end

.check_name(name) ⇒ Object

Parameters:

  • name

    The invidual member’s name that is being checked

Raises:

  • InvalidDocument if any part of the spec is not observed



428
429
430
431
432
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 428

def check_name(name)
  msg = JSONAPI::Exceptions::NamingExceptions.check_member_constraints(name)
  return if msg.nil?
  raise InvalidDocument, "The member named '#{name}' raised: #{msg}"
end

.check_patch_type(path_type, res_type, path_id, res_id) ⇒ Object

Raise 409 unless path resource type and id == endpoint resource type and id

Parameters:

  • path_type (String)

    The resource type taken from the request path

  • res_type (String)

    The resource type taken from the request body

  • path_id (String)

    The resource id taken from the path

  • res_id (String)

    The resource id taken from the request body

Raises:



479
480
481
482
483
484
485
486
487
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 479

def check_patch_type(path_type, res_type, path_id, res_id)
  check = 
    path_type.to_s.downcase.gsub(/-/, '_') == res_type.to_s.downcase.gsub(/-/, '_') &&
    path_id.to_s.downcase.gsub(/-/, '_') == res_id.to_s.downcase.gsub(/-/, '_')
  ensure!(check,
          "When processing a PATCH request, the resource object's type and id MUST " \
          "match the server's endpoint",
          status_code: 409)
end

.check_post_type(path_type, res_type) ⇒ Object

Raise 409 unless post resource type == endpoint resource type

Parameters:

  • path_type (String)

    The resource type taken from the request path

  • res_type (String)

    The resource type taken from the request body

Raises:



466
467
468
469
470
471
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 466

def check_post_type(path_type, res_type)
  ensure!(path_type.to_s.downcase.gsub(/-/, '_') == res_type.to_s.downcase.gsub(/-/, '_'),
          "When processing a POST request, the resource object's type MUST " \
          'be amoung the type(s) that constitute the collection represented by the endpoint',
          status_code: 409)
end

.check_relationship(rel) ⇒ Object

Parameters:

  • rel (Hash)

    A relationship object



217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 217

def check_relationship(rel)
  ensure!(rel.is_a?(Hash), 'Each relationships member MUST be a object')
  ensure!(!(rel.keys & RELATIONSHIP_KEYS).empty?,
          'A relationship object MUST contain at least one of ' \
          "#{RELATIONSHIP_KEYS}")
  
  # If relationship is a To-Many relationship, the links member may also have pagination links
  #   that traverse the pagination data
  check_relationship_links(rel[:links]) if rel.key? :links
  check_relationship_data(rel[:data]) if rel.key? :data
  check_meta(rel[:meta]) if rel.key? :meta
end

.check_relationship_data(data) ⇒ Object

Parameters:

  • data (Hash)

    A resources relationships relationship data



243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 243

def check_relationship_data(data)
  case data
  when Hash
    check_resource_identifier(data)
  when Array
    data.each { |res_id| check_resource_identifier(res_id) }
  when nil
    # Do nothing
  else
    ensure!(false, 'Resource linkage (relationship data) MUST be either nil, an object or an array')
  end
end

Raise if links don’t contain at least one of the TO_ONE_RELATIONSHIP_LINK_KEYS TODO: If a pagination links are present, they MUST paginate the relationships not the related resource data

Parameters:

  • links (Hash)

    A resource’s relationships’ relationship-links



234
235
236
237
238
239
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 234

def check_relationship_links(links)
  ensure!(!(links.keys & TO_ONE_RELATIONSHIP_LINK_KEYS).empty?,
          'A relationship link MUST contain at least one of '\
          "#{TO_ONE_RELATIONSHIP_LINK_KEYS}")
  check_links(links)
end

.check_relationships(rels) ⇒ Object

Parameters:

  • rels (Hash)

    The relationships obj for resource



209
210
211
212
213
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 209

def check_relationships(rels)
  ensure!(rels.is_a?(Hash),
          'The value of the relationships key MUST be an object')
  rels.each_value { |rel| check_relationship(rel) }
end

.check_resource(resource, http_method = nil) ⇒ Object

Parameters:

  • resource (Hash)

    The jsonapi resource object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 163

def check_resource(resource, http_method = nil)
  if http_method == 'POST'
    ensure!(resource[:type],
            'The resource object (for a post request) MUST contain at least a type member')
  else
    ensure!((resource[:type] && resource[:id]),
            'Every resource object MUST contain an id member and a type member')
  end
  ensure!(resource[:type].instance_of?(String),
          'The value of the resource type member MUST be string')
  if resource[:id]
    ensure!(resource[:id].instance_of?(String),
            'The value of the resource id member MUST be string')
  end
  # Check for sharing a common namespace is in #check_resource_members
  ensure!(JSONAPI::Exceptions::NamingExceptions.check_member_constraints(resource[:type]).nil?,
          'The values of type members MUST adhere to the same constraints as member names')
  
  check_resource_members(resource)      
end

.check_resource_identifier(res_id) ⇒ Object

Parameters:

  • res_id (Hash)

    A resource identifier object



257
258
259
260
261
262
263
264
265
266
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 257

def check_resource_identifier(res_id)
  ensure!(res_id.is_a?(Hash),
          'A resource identifier object MUST be an object')
  ensure!((res_id.keys & RESOURCE_IDENTIFIER_KEYS) == RESOURCE_IDENTIFIER_KEYS,
          'A resource identifier object MUST contain ' \
          "#{RESOURCE_IDENTIFIER_KEYS} members")
  ensure!(res_id[:id].is_a?(String), 'The resource identifier id member must be a string')
  ensure!(res_id[:type].is_a?(String), 'The resource identifier type member must be a string')
  check_meta(res_id[:meta]) if res_id.key? :meta
end

.check_resource_members(resource) ⇒ Object

Checks whether the resource members conform to the spec



187
188
189
190
191
192
193
194
195
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 187

def check_resource_members(resource)
  check_attributes(resource[:attributes]) if resource.key? :attributes
  check_relationships(resource[:relationships]) if resource.key? :relationships
  check_meta(resource[:meta]) if resource.key? :meta
  check_links(resource[:links]) if resource.key? :links
  ensure!(shares_common_namespace?(resource[:attributes], resource[:relationships]),
          'Fields for a resource object MUST share a common namespace with each ' \
          'other and with type and id')
end

.check_top_level(document, http_method) ⇒ Object

Checks if there are any errors in the top level hash

Raises:

  • InvalidDocument if any part of the spec is not observed



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 96

def check_top_level(document, http_method)
  ensure!(!(document.keys & REQUIRED_TOP_LEVEL_KEYS).empty?, 
          'A document MUST contain at least one of the following ' \
          "top-level members: #{REQUIRED_TOP_LEVEL_KEYS}")

  if document.key? :data
    ensure!(!document.key?(:errors),
            'The members data and errors MUST NOT coexist in the same document')
  else
    ensure!(!document.key?(:included),
            'If a document does not contain a top-level data key, the included ' \
            'member MUST NOT be present either')
    ensure!(http_method.nil?,
            'The request MUST include a single resource object as primary data, ' \
            'unless it is a PATCH request clearing a relationship using a relationship link')
  end
end

.clearing_relationship_link?(data, http_method, path) ⇒ Boolean

TODO: Write tests for clearing_relationship_link

Returns:

  • (Boolean)


504
505
506
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 504

def clearing_relationship_link?(data, http_method, path)
  http_method == 'PATCH' && data == [] && relationship_link?(path)
end

.contains_type_or_id_member?(hash) ⇒ Boolean

Parameters:

  • hash (Hash)

    The hash to check

Returns:

  • (Boolean)


528
529
530
531
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 528

def contains_type_or_id_member?(hash)
  return false unless hash
  hash.key?(:id) || hash.key?(:type)
end

.ensure!(condition, error_message, status_code: 400) ⇒ Object

Helper function to raise InvalidDocument errors

Parameters:

  • condition

    The condition to evaluate

  • error_message (String)

    The message to raise InvalidDocument with

Raises:

  • InvalidDocument



497
498
499
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 497

def ensure!(condition, error_message, status_code: 400)
  raise InvalidDocument.new(status_code), error_message unless condition
end

.full_linkage?(document) ⇒ Boolean

Parameters:

  • document (Hash)

    The jsonapi document hash

Returns:

  • (Boolean)


544
545
546
547
548
549
550
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 544

def full_linkage?(document)
  return true unless document[:included] 
  # ^ Checked earlier to make sure included only exists w data
  
  possible_includes = get_possible_includes(document)
  any_additional_includes?(possible_includes, document[:included])
end

.get_possible_includes(document) ⇒ Hash

Get a collection of all possible includes

Need to check relationships on primary resource(s) and also
relationships on the included resource(s)

Returns:

  • (Hash)

    Collection of possible includes



557
558
559
560
561
562
563
564
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 557

def get_possible_includes(document)
  possible_includes = {}
  primary_data = document[:data]
  include_arr = document[:included]
  populate_w_primary_data(possible_includes, primary_data)
  populate_w_include_mem(possible_includes, include_arr)
  possible_includes
end

.keys_intersection_empty?(arr1, arr2) ⇒ Boolean

Checks to see if two hashes share any key members names

Parameters:

  • arr1 (Array<Symbol>)

    The first hash key array

  • arr2 (Array<Symbol>)

    The second hash key array

Returns:

  • (Boolean)


536
537
538
539
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 536

def keys_intersection_empty?(arr1, arr2)
  return true unless arr1 && arr2
  arr1.keys & arr2.keys == []
end

.populate_w_include_mem(possible_includes, include_arr) ⇒ Object

Parameters:

  • include_arr (Array<Hash>)

    The array of includes



589
590
591
592
593
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 589

def populate_w_include_mem(possible_includes, include_arr)
  include_arr.each do |res|
    populate_w_res_rels(possible_includes, res)
  end
end

.populate_w_primary_data(possible_includes, primary_data) ⇒ Object

Parameters:

  • primary_data (Hash)

    The primary data of a document



577
578
579
580
581
582
583
584
585
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 577

def populate_w_primary_data(possible_includes, primary_data)
  if primary_data.is_a? Array
    primary_data.each do |res|
      populate_w_res_rels(possible_includes, res)
    end
  else
    populate_w_res_rels(possible_includes, primary_data)
  end
end

.populate_w_res_rels(possible_includes, resource) ⇒ Object

Parameters:

  • resource (Hash)

    The resource to check



597
598
599
600
601
602
603
604
605
606
607
608
609
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 597

def populate_w_res_rels(possible_includes, resource)
  return unless resource[:relationships]
  resource[:relationships].each_value do |rel|
    res_id = rel[:data]
    next unless res_id

    if res_id.is_a? Array
      res_id.each { |id| possible_includes[res_id_to_sym(id[:type], id[:id])] = true }
    else
      possible_includes[res_id_to_sym(res_id[:type], res_id[:id])] = true
    end
  end
end

.relationship_link?(path) ⇒ Boolean

Does the path length and values indicate that it is a relationsip link

Parameters:

  • path (String)

    The request path

Returns:

  • (Boolean)


510
511
512
513
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 510

def relationship_link?(path)
  path_arr = path.split('/')
  path_arr[-2] == 'relationships' && path_arr.length >= 4
end

.res_id_to_sym(type, id) ⇒ Object

Creates a hash key using type and id

Parameters:

  • type (String)

    the resource type

  • id (String)

    the resource id



614
615
616
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 614

def res_id_to_sym(type, id)
  "#{type}|#{id}".to_sym
end

.shares_common_namespace?(attributes, relationships) ⇒ Boolean

Checks whether a resource’s fields share a common namespace

Parameters:

  • attributes (Hash)

    A resource’s attributes

  • relationships (Hash)

    A resource’s relationships

Returns:

  • (Boolean)


520
521
522
523
524
525
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 520

def shares_common_namespace?(attributes, relationships)
  true && \
    !contains_type_or_id_member?(attributes) && \
    !contains_type_or_id_member?(relationships) && \
    keys_intersection_empty?(attributes, relationships)
end

.unique_pair?(set, res) ⇒ TrueClass | FalseClass

Returns Whether the resource has a unique type and id pair.

Parameters:

  • set (Hash)

    Set of unique pairs so far

  • res (Hash)

    The resource to inspect

Returns:

  • (TrueClass | FalseClass)

    Whether the resource has a unique type and id pair



302
303
304
305
306
307
308
309
# File 'lib/easy/jsonapi/exceptions/document_exceptions.rb', line 302

def unique_pair?(set, res)
  pair = "#{res[:type]}|#{res[:id]}"
  if set.key?(pair)
    return false
  end
  set[pair] = true
  true
end