Rails api控制器中如何处理服务对象异常
Rails api how to handle service object exceptions in controller
我想在 Rails API 中使用服务对象。在我的服务对象中,如果保存成功,我想保存模型和 return true,但如果保存不成功,我想 return false 并发送错误消息。我的服务对象看起来像这样:
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
问题是我不知道如何发送错误消息作为响应。当我尝试发送 service_object.errors.messages 时,它向我显示一个空数组。在 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
那么如何从 Controller 中的服务对象获取模型错误?
您可以通过向您的服务对象提供方法来解决此问题,即使在 save_model
以 false
返回后也允许返回模型或错误。
我会将服务对象更改为
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
控制器方法
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
我会重构服务对象,使其只委托给底层模型:
class ModelSaver
attr_reader :model
delegate :errors, to: :model
def initialize(**params)
@model = Model.new(**params)
end
def save_model
if model.save
true
else
model.errors.add(:base, 'you forgot to frobnobize the whatchamacallit')
false
end
end
end
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
我想在 Rails API 中使用服务对象。在我的服务对象中,如果保存成功,我想保存模型和 return true,但如果保存不成功,我想 return false 并发送错误消息。我的服务对象看起来像这样:
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
问题是我不知道如何发送错误消息作为响应。当我尝试发送 service_object.errors.messages 时,它向我显示一个空数组。在 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
那么如何从 Controller 中的服务对象获取模型错误?
您可以通过向您的服务对象提供方法来解决此问题,即使在 save_model
以 false
返回后也允许返回模型或错误。
我会将服务对象更改为
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
控制器方法
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
我会重构服务对象,使其只委托给底层模型:
class ModelSaver
attr_reader :model
delegate :errors, to: :model
def initialize(**params)
@model = Model.new(**params)
end
def save_model
if model.save
true
else
model.errors.add(:base, 'you forgot to frobnobize the whatchamacallit')
false
end
end
end
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