Перейти к основному содержимому
Версия: 1.8

Вызов сервиса и результат работы

Вызов сервиса

Сервисы могут быть вызваны только через методы .call и .call!.

Через .call!

Вызов через метод .call! будет падать при любом виде исключения.

UsersService::Accept.call!(user: User.first)

Через .call

Вызов через метод .call будет падать с ошибкой только в том случае, если он перехватит исключение в input-аргументах. Ошибки, возникшие в атрибутах internal и output, а также ошибки, возникшие в методах — все это будет собрано в Result сервиса.

UsersService::Accept.call(user: User.first)

Результат

Все сервисы имеют результат своей работы. Например, в случае успеха этот вызов:

service_result = UsersService::Accept.call(user: User.first)

Будет возвращать это:

#<Servactory::Result @user=...>

И затем можно работать с этим результатом, например, таким образом:

Notification::SendJob.perform_later(service_result.user.id)

Содержимое результата

Выходящие атрибуты

Все что было добавлено через метод output в сервисе будет доступно в Result.

Output'ы в Result имеют методы предикаты аналогично тому как внутри сервиса.

Хелперы

В результате работы сервиса присутствуют методы success? и failure?, которые могут помочь определить результат работы для дальнейшей обработки.

service_result.success? # => true
service_result.failure? # => false

Ошибка

Информацию об ошибке можно получить через метод error.

service_result.error

# => <ApplicationService::Errors::Failure: Invalid invoice number>

Информация

Снаружи сервиса можно получить информацию о его input, internal и output атрибутах.

Это может быть полезно, например, при реализации сложной обработки классов.

Например, в сервисе описаны следующие атрибуты:

class BuildFullName < ApplicationService::Base
input :first_name, type: String
input :middle_name, type: String, required: false
input :last_name, type: String

internal :prepared_full_name, type: String

output :full_name, type: String

# ...
end

Получить информацию о них можно следующими способами:

BuildFullName.info

# => <Servactory::Info::Result:0x00000001118c7078 @inputs=[:first_name, :middle_name, :last_name], @internals=[:prepared_full_name], @outputs=[:full_name]>
BuildFullName.info.inputs

# => [:first_name, :middle_name, :last_name]
BuildFullName.info.internals

# => [:prepared_full_name]
BuildFullName.info.outputs

# => [:full_name]