You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 02:09:01