27 Apr Rails: How to respond with custom error messages in the ActiveRecord way without having a model
Here you have a quick example:
Let’s begin with the service for that.
app/services/format_response_with_active_model_errors.rb
class FormatResponseWithActiveModelErrors
extend ActiveModel::Naming
def initialize
@errors = ActiveModel::Errors.new(self)
end
def valid?
errors.empty?
end
attr_reader :errors
attr_accessor :response
def add_error_message!(field_name:, message:)
errors.add(field_name, message)
end
def read_attribute_for_validation(attr)
send(attr)
end
# Needed when using the errors.full_messages method
def self.human_attribute_name(attr, options = {})
attr
end
# Needed for translations
def self.lookup_ancestors
[self]
end
end
And we are going to use it within another service class
app/services/my_service.rb
class MyService
def self.calculate_a_thing(params)
response_with_errors = FormatResponseWithActiveModelErrors.new
if condition_true?
response_with_errors.add_error_message!(
field_name: 'my_field_name',
message: 'Custom error message'
)
return response_with_errors
end
if another_condition?
response_with_errors.add_error_message!(
field_name: 'my_field_name_2',
message: 'Custom error message'
)
return response_with_errors
end
response_with_errors
rescue StandardError => e
logger.info '-------------'
response_with_errors.add_error_message!(
field_name: 'unexpected_exception',
message: "An exception has ocurred when creating sessions/tokens for Opentok #{e.to_s}"
)
response_with_errors
end
end
Finally, it is time to render errors inside our controller:
app/controllers/api/v1/patients_controller.rb
module Api
module V1
class PatientsController < V1::ApplicationController
def calculate_something
service_response = MyService.calculate_a_thing(my_strong_parameters)
if service_response.valid?
render json { ... }, status: :ok
else
render json: service_response.errors, status: 422
end
end
end
end
There you go!, keep reading, coding and relax!
No Comments