Using options in attributes
Option type input internal output
This option is validation. It will check that the passed value corresponds to the specified type (class). The is_a? method is used.
Always required to specify. May contain one or more classes.
class NotificationsService::Create < ApplicationService::Base
input :user, type: User
input :need_to_notify, type: [TrueClass, FalseClass]
# ...
endclass NotificationsService::Create < ApplicationService::Base
# ...
internal :inviter, type: User
# ...
endclass NotificationsService::Create < ApplicationService::Base
# ...
output :notification, type: Notification
# ...
endOption required input
This option is validation. It will check that the passed value is not empty. The present? method is used.
By default, required is set to true.
class UsersService::Create < ApplicationService::Base
input :first_name,
type: String
input :middle_name,
type: String,
required: false
input :last_name,
type: String
# ...
endOption default input
This option is not validation. It will assign a value to the attribute if one was not passed to the service.
class UsersService::Create < ApplicationService::Base
# ...
input :middle_name,
type: String,
required: false,
default: "<unknown>"
# ...
endOption as input
This option is not validation. It will indicate the new name of the attribute to work within the service. The original name inside the service will no longer be available.
class NotificationsService::Create < ApplicationService::Base
input :user,
as: :recipient,
type: User
# ...
def create!
outputs.notification =
Notification.create!(recipient: inputs.recipient)
end
endOption inclusion input internal (^2.2.0) output (^2.2.0)
INFO
Since version 2.12.0 this option is dynamic.
This option is validation. This option is dynamic. It will check that the passed value is in the specified array. The include? method is used.
class EventsService::Send < ApplicationService::Base
input :event_name,
type: String,
inclusion: %w[created rejected approved]
# ...
endclass EventsService::Send < ApplicationService::Base
# ...
internal :event_name,
type: String,
inclusion: %w[created rejected approved]
# ...
endclass EventsService::Send < ApplicationService::Base
# ...
output :event_name,
type: String,
inclusion: %w[created rejected approved]
# ...
endOption consists_of input (^2.0.0) internal (^2.0.0) output (^2.0.0)
INFO
Since version 2.6.0 this option is dynamic.
This option is validation. This option is dynamic. It will check that each value in the collection matches the specified type (class). Checks nested values. The is_a? method is used.
Works only with Array and Set types. You can add a custom type through the collection_mode_class_names configuration.
Explicit use of this option is optional. The default value is String.
input :ids,
type: Array,
consists_of: Stringinternal :ids,
type: Array,
consists_of: Stringoutput :ids,
type: Array,
consists_of: StringOption schema input (^2.0.0) internal (^2.0.0) output (^2.0.0)
INFO
Since version 2.12.0 this option is dynamic.
This option is validation. This option is dynamic. Requires a hash value that must describe the value structure of the output attribute.
Only works with the Hash type. You can add a custom type through the hash_mode_class_names configuration.
Explicit use of this option is optional. If the schema value is not specified, the validation will be skipped. By default, no value is specified.
input :payload,
type: Hash,
schema: {
request_id: { type: String, required: true },
user: {
type: Hash,
required: true,
first_name: { type: String, required: true },
middle_name: { type: String, required: false, default: "<unknown>" },
last_name: { type: String, required: true },
pass: {
type: Hash,
required: true,
series: { type: String, required: true },
number: { type: String, required: true }
}
}
}internal :payload,
type: Hash,
schema: {
request_id: { type: String, required: true },
user: {
type: Hash,
required: true,
first_name: { type: String, required: true },
middle_name: { type: String, required: false, default: "<unknown>" },
last_name: { type: String, required: true },
pass: {
type: Hash,
required: true,
series: { type: String, required: true },
number: { type: String, required: true }
}
}
}output :payload,
type: Hash,
schema: {
request_id: { type: String, required: true },
user: {
type: Hash,
required: true,
first_name: { type: String, required: true },
middle_name: { type: String, required: false, default: "<unknown>" },
last_name: { type: String, required: true },
pass: {
type: Hash,
required: true,
series: { type: String, required: true },
number: { type: String, required: true }
}
}
}Each expected hash key must be described in the following format:
{
request_id: { type: String, required: true }
}The following options are allowed: mandatory type, required and optional default, prepare. The default and prepare options are only available when used within input.
If type also specifies a Hash value, then nesting can be described in the same format.
Option must input internal (^2.2.0) output (^2.2.0)
This option is validation. Allows you to create your own validations.
class PaymentsService::Create < ApplicationService::Base
input :invoice_numbers,
type: Array,
consists_of: String,
must: {
be_6_characters: {
is: ->(value:, input:) { value.all? { |id| id.size == 6 } }
}
}
# ...
endclass EventsService::Send < ApplicationService::Base
# ...
internal :invoice_numbers,
type: Array,
consists_of: String,
must: {
be_6_characters: {
is: ->(value:, internal:) { value.all? { |id| id.size == 6 } }
}
}
# ...
endclass EventsService::Send < ApplicationService::Base
# ...
output :invoice_numbers,
type: Array,
consists_of: String,
must: {
be_6_characters: {
is: ->(value:, output:) { value.all? { |id| id.size == 6 } }
}
}
# ...
endOption format input (^2.4.0) internal (^2.4.0) output (^2.4.0)
This option is validation. This option is dynamic and is not part of the main options.
Option max input (^2.4.0) internal (^2.4.0) output (^2.4.0)
This option is validation. This option is dynamic and is not part of the main options.
Option min input (^2.4.0) internal (^2.4.0) output (^2.4.0)
This option is validation. This option is dynamic and is not part of the main options.
Option prepare input
This option is not validation. It is used to prepare the passed value.
WARNING
Use the prepare option carefully and only for simple preparatory actions. For example, as shown below. Any logic that is more complex than that in the example below is better applied through the make action.
class PaymentsService::Create < ApplicationService::Base
input :amount_cents,
as: :amount,
type: Integer,
prepare: ->(value:) { Money.from_cents(value, :USD) }
# ...
def create!
outputs.payment = Payment.create!(amount: inputs.amount)
end
end