Rails API控制器如何获取Service Object中的Model错误信息
问题根因
你在Service类中引入了ActiveModel::Validations后,Service实例自身的errors和内部创建的Model实例的errors是完全独立的两个对象。你现有代码中所有错误都被添加到了内部Model实例上,没有同步到Service实例的errors中,因此Controller中读取service_object.errors自然返回空。
同时你原有save_model的逻辑存在冗余:先调用model.valid?执行校验,再调用model.save!时会默认再次执行一遍校验,重复执行了校验逻辑。
解决方案
修改Service Object代码,将Model实例的错误主动同步到Service实例的errors中即可,修改后代码如下:
class ModelSaver include ActiveModel::Validations def initialize(params) @params = params @model = Model.new(params) end def save_model if @model.save true else # 同步Model所有错误到Service实例 @model.errors.each do |attribute, message| errors.add(attribute, message) end # 添加你需要的全局默认错误 errors.add(:base, 'here I want default error message') false end end # 可选:开放model实例的读取权限,方便Controller在成功时返回model数据 attr_reader :model private attr_reader :params end
如果你的场景需要通过异常捕获处理数据库层面触发的校验错误(比如唯一索引约束报错),可以保留异常捕获的写法,调整为如下版本:
def save_model @model.save! true rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique @model.errors.each do |attribute, message| errors.add(attribute, message) end errors.add(:base, 'here I want default error message') false end
修改后你的Controller代码不需要做任何调整,即可正常通过service_object.errors.messages拿到所有错误信息。
内容的提问来源于stack exchange,提问作者N0ne
相关产品推荐
相关产品推荐

