Сервисный объект возвращает статус
Я делаю рельсы 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