I wanted use Service Object in my Rails API. Inside my Service Object I want to save Model and return true if saving was successful, but if saving was unsuccessful then I want to return false and send error messages. My Service Object looks like that:
class ModelSaver
include ActiveModel::Validations
def initialize(params)
@params = params
end
def save_model
model ||= Model.new(params)
return false unless model.valid?
model.save!
rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
model.errors.add(:base, 'here I want default error message')
false
end
private
attr_reader :params
end
The problem is that I don't know how to send errors messages in response. When I try to send service_object.errors.messages it displays an empty array to me. It looks like that in Controller:
class ModelController < ApplicationController
...
def create
service_object = ModelSaver.new(params)
if service_object.save_model
render json: service_object
else
render json: { errors: service_object.errors.messages }, status: :unprocessable_entity
end
end
...
end
So how can I get Model errors from Service Object inside Controller?
You can solve this by providing methods to your service object that allow returning the model or the errors even after save_model
returned with false
.
I would change the service object to
class ModelSaver
include ActiveModel::Validations
attr_reader :model
def initialize(params)
@params = params
end
def errors
@model.errors
end
def save_model
@model ||= Model.new(params)
return false unless model.valid?
@model.save!
rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
@model.errors.add(:base, 'here I want default error message')
false
end
private
attr_reader :params
end
and the controller method to
def create
service_object = ModelSaver.new(params)
if service_object.save_model
render json: service_object.model
else
render json: { errors: service_object.errors.messages }, status: :unprocessable_entity
end
end