Ответ 1
Для простых случаев (например, только с одним аргументом), ваш чек-рейз с ArgumentError в порядке. Как только вы начинаете создавать сложные случаи (несколько аргументов, объектов и т.д.), Я начинаю полагаться на Virtus и Проверки ActiveModel.
Ваша связанная статья фактически упоминает их (см. "Извлечь объекты формы" ). Я иногда использую что-то вроде этого для создания служебных объектов, например.
require 'active_model'
require 'virtus'
class CreatePackage
include Virtus
include ActiveModel::Validations
attribute :name, String
attribute :author, String
validates_presence_of :name, :author
def create
raise ArgumentError.new("Invalid package") unless self.valid?
response = JSON.parse(
API::post("/packages", self.attributes),
:symbolize_names => true
)
Package.new(response)
end
end
class Package
include Virtus
attribute :id, Integer
attribute :name, String
attribute :author, String
end
# eg.
service = CreatePackage.new(
:name => "Tim Tams",
:author => "Tim",
)
service.valid? # true; if false, see service.errors
package = service.create
package.attributes
# => { :id => 123, :name => "Tim Tams", :author => "Tim" }
Что касается исключений, я бы оставил их как есть для меньших действий (например, этот класс обслуживания). Я мог бы обернуть их, если я напишу что-то более существенное, например, всю клиентскую библиотеку API.
Я бы никогда не вернул ноль. Такие вещи, как сетевая ошибка или плохой или непроверяемый ответ с сервера, имеют явные ошибки.
Наконец, существует более тяжелый подход, называемый use_case. Даже если вы не используете его, у него есть куча идей о том, как решать объекты обслуживания, проверки и результаты, которые могут вам показаться интересными.
Изменить. Также проверьте Mutations. Как use_case, кроме более простых и менее всеобъемлющих.