Сервисный объект возвращает статус

Я делаю рельсы 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

И мой вопрос заключается в том, должен ли я возвращать простой текст из сервисного объекта или есть какой-то лучший подход?

1 ответ

Решение

Это, конечно, будет самоуверенным, но все же...

Рендеринг представлений с данными, возврат данных, перенаправление и т. Д. Являются обязанностью контроллеров. Таким образом, любые данные, простой текст и другие вещи, которые вы должны обрабатывать в вашем контроллере.

Служебный объект должен предоставить один открытый метод для выполнения любой сложной сложной операции. И очевидно, что метод должен возвращать простое значение, которое сообщает контроллеру, была ли операция успешно завершена или нет. Так должно быть true или же false, Может быть, какой-то узнаваемый результат (объект, простое значение) или errors хэш. Конечно, это идеальный вариант использования, но это главное.

Что касается вашего варианта использования, ваша служба может вернуть сообщение или 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
Другие вопросы по тегам