Ruby on rails 服务对象返回状态

Ruby on rails 服务对象返回状态,ruby-on-rails,rails-api,service-object,Ruby On Rails,Rails Api,Service Object,我正在制作一个rails json api,它在控制器操作中使用服务对象,并根据服务中发生的事情来呈现适当的json。示例如下所示 star_service.rb class Place::StarService def initialize(params, user) @place_id = params[:place_id] @user = user end def call if UserStaredPlace.find_by(user: user,

我正在制作一个rails json api,它在控制器操作中使用服务对象,并根据服务中发生的事情来呈现适当的json。示例如下所示

star_service.rb

class Place::StarService
  def initialize(params, user)
    @place_id = params[:place_id]
    @user = user
  end

  def call
    if UserStaredPlace.find_by(user: user, place_id: place_id)
      return #star was already given
    end

    begin
      ActiveRecord::Base.transaction do
        Place.increment_counter(:stars, place_id)
        UserStaredPlace.create(user: user, place_id: place_id)
      end
    rescue
      return #didn't work
    end

    return #gave a star
  end

  private

  attr_reader :place_id, :user
end
places_controller.rb

def star
  foo_bar = Place::Star.new(params, current_user).call

  if foo_bar == #sth
    render json: {status: 200, message: "sth"}
  elsif foo_bar == #sth
    render json: {status: 200, message: "sth"}
  else
    render json: {status: 400, message: "sth"}
end

我的问题是,如果我应该从服务对象返回纯文本,还是有更好的方法?

当然,这是自以为是的,但仍然

使用数据呈现视图、返回数据、重定向等是控制器的职责。因此,任何数据、纯文本和其他您必须在控制器中处理的内容

服务对象必须为执行的任何大型复杂操作提供一个单一的公共方法。显然,该方法必须返回简单的值,告诉控制器操作是否成功完成。因此它必须是
true
false
。可能是一些可识别的结果(对象、简单值)或
错误
散列。这当然是一个理想的用例,但这是关键

对于您的用例,您的服务可能会返回消息或
false
。然后控制器将该消息呈现为
json

您的
star
方法必须位于控制器中,可能是私有的,并且看起来是这样的:

def star
  foo_bar = Place::Star.new(params, current_user).call

  if foo_bar
    render json: {status: 200, message: foobar} 
  else
    render json: {status: 400, message: "Failed"}
  end
end
您的服务:

class Place::StarService
  def initialize(params, user)
    @place_id = params[:place_id]
    @user = user
  end

  def call
    if UserStaredPlace.find_by(user: user, place_id: place_id)
      return "Message when star is already given"
    end

    begin
      ActiveRecord::Base.transaction do
        Place.increment_counter(:stars, place_id)
        UserStaredPlace.create(user: user, place_id: place_id)
      end
    rescue
      return false
    end

    return "Message if gave a star"
  end

  private

  attr_reader :place_id, :user
end

所以你是说我应该删除服务并将逻辑移到控制器?对不起,我重新考虑了一下答案并更新了它。不,您不需要删除服务。服务就是生命!:)服务返回结果或false。控制器的操作(可能使用私有方法)如果结果不是
false