# frozen_string_literal: true class Things::Something Result = Data.define(:thing, :errors) do def initialize(thing: nil, errors: []) super end def successful? errors.empty? end end def self.call(params, scope = ThingModel) new(params, scope).call end def call something = find_or_process_things if something.successful? Result.new(thing: something) else Result.new(errors: something.errors, thing: something) end end def initialize(params, scope) @params = params @scope = scope end private_class_method :new private def find_or_process_things @scope.where(...) end end # Usage result = Things::Something.call(params) # => Things::Something::Result result.successful? # => true result.errors # => [] result.thing # =>