0

我想在我的 Rails API 中使用服务对象。在我的服务对象中,如果保存成功,我想保存模型并返回 true,但如果保存不成功,那么我想返回 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 中的服务对象获取模型错误呢?

4

2 回答 2

0

您可以通过向服务对象提供方法来解决此问题,这些方法允许返回模型或错误,即使在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
于 2021-09-01T19:20:04.223 回答
0

我将重构服务对象,使其仅委托给底层模型:

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
于 2021-09-01T19:21:48.240 回答