Skip to content

Commit

Permalink
Simplify ActiveModel::ErrorSerializer
Browse files Browse the repository at this point in the history
We're only running CI for Rails 6.1+ now, and we can now rely on a
stable API for ActiveModel::Errors.
  • Loading branch information
mamhoff committed Feb 1, 2024
1 parent da08b5b commit 89f6e61
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 51 deletions.
28 changes: 4 additions & 24 deletions lib/jsonapi/active_model_error_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,15 @@ class ActiveModelErrorSerializer < ErrorSerializer
end

attribute :code do |object|
_, error_hash = object
code = error_hash[:error] unless error_hash[:error].is_a?(Hash)
code ||= error_hash[:message] || :invalid
# `parameterize` separator arguments are different on Rails 4 vs 5...
code.to_s.delete("''").parameterize.tr('-', '_')
object.type.to_s.delete("''").parameterize.tr('-', '_')
end

attribute :detail do |object, params|
error_key, error_hash = object
errors_object = params[:model].errors

# Rails 4 provides just the message.
if error_hash[:error].present? && error_hash[:error].is_a?(Hash)
message = errors_object.generate_message(
error_key, nil, error_hash[:error]
)
elsif error_hash[:error].present?
message = errors_object.generate_message(
error_key, error_hash[:error], error_hash
)
else
message = error_hash[:message]
end

errors_object.full_message(error_key, message)
attribute :detail do |object, _params|
object.full_message
end

attribute :source do |object, params|
error_key, _ = object
error_key = object.attribute
model_serializer = params[:model_serializer]
attrs = (model_serializer.attributes_to_serialize || {}).keys
rels = (model_serializer.relationships_to_serialize || {}).keys
Expand Down
28 changes: 4 additions & 24 deletions lib/jsonapi/rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def self.add_errors_renderer!
JSONAPI::ErrorSerializer.new(resource, options)
) unless resource.is_a?(ActiveModel::Errors)

errors = []
model = resource.instance_variable_get(:@base)

if respond_to?(:jsonapi_serializer_class, true)
Expand All @@ -55,31 +54,12 @@ def self.add_errors_renderer!
model_serializer = JSONAPI::Rails.serializer_class(model, false)
end

details = {}
if ::Rails.gem_version >= Gem::Version.new('6.1')
resource.each do |error|
attr = error.attribute
details[attr] ||= []
details[attr] << error.detail.merge(message: error.message)
end
elsif resource.respond_to?(:details)
details = resource.details
else
details = resource.messages
end

details.each do |error_key, error_hashes|
error_hashes.each do |error_hash|
# Rails 4 provides just the message.
error_hash = { message: error_hash } unless error_hash.is_a?(Hash)

errors << [ error_key, error_hash ]
end
end

JSONAPI::Rails.serializer_to_json(
JSONAPI::ActiveModelErrorSerializer.new(
errors, params: { model: model, model_serializer: model_serializer }
resource.errors, params: {
model: model,
model_serializer: model_serializer
}
)
)
end
Expand Down
1 change: 0 additions & 1 deletion spec/dummy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ def self.ransackable_attributes(auth_object = nil)
end

private

def title_cannot_contain_slurs
errors.add(:base, 'Title has slurs') if title.to_s.include?('SLURS')
end
Expand Down
9 changes: 7 additions & 2 deletions spec/errors_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,17 @@
it do
expect(response).to have_http_status(:unprocessable_entity)
expect(response_json['errors'].size).to eq(1)
expected_detail = if Rails.gem_version >= Gem::Version.new('6.1')
'User must exist'
else
'User can\'t be blank'
end
expect(response_json['errors']).to contain_exactly(
{
'status' => '422',
'source' => { 'pointer' => '/data/relationships/user' },
'title' => 'Unprocessable Entity',
'detail' => Rails.gem_version >= Gem::Version.new('6.1') ? 'User must exist' : 'User can\'t be blank',
'detail' => expected_detail,
'code' => 'blank'
}
)
Expand Down Expand Up @@ -102,7 +107,7 @@
end
end

context "validations with non-interpolated messages" do
context 'validations with non-interpolated messages' do
let(:params) do
payload = note_params.dup
payload[:data][:attributes][:title] = 'SLURS ARE GREAT'
Expand Down

0 comments on commit 89f6e61

Please sign in to comment.