Skip to content

Commit 2477ad9

Browse files
committed
Merge pull request #315 from pmukerji/error-source-instead-of-path
Use source for errors instead of path
2 parents a64148a + 8fb0f4d commit 2477ad9

4 files changed

Lines changed: 31 additions & 19 deletions

File tree

lib/jsonapi/error.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module JSONAPI
22
class Error
3-
attr_accessor :title, :detail, :id, :href, :code, :path, :links, :status
3+
attr_accessor :title, :detail, :id, :href, :code, :source, :links, :status
44

55
def initialize(options = {})
66
@title = options[:title]
@@ -12,7 +12,7 @@ def initialize(options = {})
1212
else
1313
options[:code]
1414
end
15-
@path = options[:path]
15+
@source = options[:source]
1616
@links = options[:links]
1717
@status = options[:status]
1818
end

lib/jsonapi/exceptions.rb

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,11 @@ def errors
294294
end
295295

296296
class ValidationErrors < Error
297-
attr_accessor :messages
298-
def initialize(messages)
299-
@messages = messages
297+
attr_reader :error_messages, :resource_associations
298+
299+
def initialize(resource)
300+
@error_messages = resource.model.errors.messages
301+
@resource_associations = resource.class._associations.keys
300302
@key_formatter = JSONAPI.configuration.key_formatter
301303
end
302304

@@ -305,16 +307,26 @@ def format_key(key)
305307
end
306308

307309
def errors
308-
messages.inject([]) do |arr, element|
309-
arr.concat(
310-
element[1].map do |message|
311-
JSONAPI::Error.new(code: JSONAPI::VALIDATION_ERROR,
312-
status: :unprocessable_entity,
313-
title: "#{format_key(element[0])} - #{message}",
314-
detail: message,
315-
path: "/#{element[0]}")
316-
end
317-
)
310+
error_messages.flat_map do |attr_key, messages|
311+
messages.map { |message| json_api_error(attr_key, message) }
312+
end
313+
end
314+
315+
private
316+
317+
def json_api_error(attr_key, message)
318+
JSONAPI::Error.new(code: JSONAPI::VALIDATION_ERROR,
319+
status: :unprocessable_entity,
320+
title: "#{format_key(attr_key)} - #{message}",
321+
detail: message,
322+
source: { pointer: pointer(attr_key) })
323+
end
324+
325+
def pointer(attr_or_association_name)
326+
if resource_associations.include?(attr_or_association_name)
327+
"/data/relationships/#{attr_or_association_name}"
328+
else
329+
"/data/attributes/#{attr_or_association_name}"
318330
end
319331
end
320332
end
@@ -358,7 +370,7 @@ class InvalidPageValue < Error
358370
def initialize(page, value, msg = nil)
359371
@page = page
360372
@value = value
361-
@msg = msg.nil? ? "#{value} is not a valid value for #{page} page parameter." : msg
373+
@msg = msg || "#{value} is not a valid value for #{page} page parameter."
362374
end
363375

364376
def errors

lib/jsonapi/resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def save
138138
# ```
139139
def _save
140140
unless @model.valid?
141-
fail JSONAPI::Exceptions::ValidationErrors.new(@model.errors.messages)
141+
fail JSONAPI::Exceptions::ValidationErrors.new(self)
142142
end
143143

144144
if defined? @model.save

test/controllers/controller_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,11 +391,11 @@ def test_create_with_invalid_data
391391

392392
assert_response :unprocessable_entity
393393

394-
assert_equal "/author", json_response['errors'][0]['path']
394+
assert_equal "/data/relationships/author", json_response['errors'][0]['source']['pointer']
395395
assert_equal "can't be blank", json_response['errors'][0]['detail']
396396
assert_equal "author - can't be blank", json_response['errors'][0]['title']
397397

398-
assert_equal "/title", json_response['errors'][1]['path']
398+
assert_equal "/data/attributes/title", json_response['errors'][1]['source']['pointer']
399399
assert_equal "is too long (maximum is 35 characters)", json_response['errors'][1]['detail']
400400
assert_equal "title - is too long (maximum is 35 characters)", json_response['errors'][1]['title']
401401
end

0 commit comments

Comments
 (0)