Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions lib/jsonapi/active_model_error_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ class ActiveModelErrorSerializer < ErrorSerializer

attribute :code do |object|
_, error_hash = object
code = error_hash[:error] unless error_hash[:error].is_a?(Hash)
unless error_hash[:error].is_a?(Hash) || error_hash[:error].is_a?(String)
code = error_hash[:error]
end
code ||= error_hash[:message] || :invalid
# `parameterize` separator arguments are different on Rails 4 vs 5...
code.to_s.delete("''").parameterize.tr('-', '_')
Expand All @@ -29,9 +31,15 @@ class ActiveModelErrorSerializer < ErrorSerializer
error_key, nil, error_hash[:error]
)
elsif error_hash[:error].present?
message = errors_object.generate_message(
error_key, error_hash[:error], error_hash
)
# if the error was added as a string, we do not need to generate an
# error message, but use the error as is
if error_hash[:error].is_a?(String)
message = error_hash[:error]
else
message = errors_object.generate_message(
error_key, error_hash[:error], error_hash
)
end
else
message = error_hash[:message]
end
Expand Down
15 changes: 15 additions & 0 deletions spec/dummy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ class Note < ActiveRecord::Base
validates_format_of :title, without: /BAD_TITLE/
validates_numericality_of :quantity, less_than: 100, if: :quantity?
belongs_to :user, required: true

validate :nice_title

# this validation is added to test that a validation error added as a string
# (instead of a symbol) works as well
#
# see https://api.rubyonrails.org/v7.0.8.7/classes/ActiveModel/Errors.html#method-i-add
#
# > If `type` is a string, it will be used as error message.
#
def nice_title
return unless title == 'NOT_SO_NICE_TITLE'

errors.add(:title, 'is not so nice')
end
end

class CustomNoteSerializer
Expand Down
21 changes: 21 additions & 0 deletions spec/errors_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,27 @@
end
end

context 'with a validation error type that is a string' do
let(:params) do
payload = note_params.dup
payload[:data][:attributes][:title] = 'NOT_SO_NICE_TITLE'
payload
end

it do
expect(response).to have_http_status(:unprocessable_entity)
expect(response_json['errors'].size).to eq(2)
expect(response_json['errors'][0]['status']).to eq('422')
expect(response_json['errors'][0]['code']).to include('invalid')
expect(response_json['errors'][0]['title'])
.to eq(Rack::Utils::HTTP_STATUS_CODES[422])
expect(response_json['errors'][0]['source'])
.to eq('pointer' => '/data/attributes/title')
expect(response_json['errors'][0]['detail'])
.to eq('Title is not so nice')
end
end

context 'as a param attribute' do
let(:params) do
payload = note_params.dup
Expand Down
6 changes: 6 additions & 0 deletions spec/pagination_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,16 @@

context 'on page 2 out of 3' do
let(:as_list) { }
# .compact_blank is not available in our Rails version
# rubocop:disable Rails/CompactBlank
let(:params) do
{
page: { number: 2, size: 1 },
sort: '-created_at',
as_list: as_list
}.reject { |_k, _v| _v.blank? }
end
# rubocop:enable Rails/CompactBlank

context 'on an array of resources' do
let(:as_list) { true }
Expand Down Expand Up @@ -153,12 +156,15 @@

context 'on paging beyond the last page' do
let(:as_list) { }
# .compact_blank is not available in our Rails version
# rubocop:disable Rails/CompactBlank
let(:params) do
{
page: { number: 5, size: 1 },
as_list: as_list
}.reject { |_k, _v| _v.blank? }
end
# rubocop:enable Rails/CompactBlank

context 'on an array of resources' do
let(:as_list) { true }
Expand Down
Loading