DEV: Make service contracts immutable

We decided to make contracts immutable once their validations have run.
Indeed, it doesn’t make a lot of sense to modify a contract value
outside the contract itself.

If processing is needed, then it should happen inside the contract
itself.
This commit is contained in:
Loïc Guitaut
2024-10-28 16:04:39 +01:00
committed by Loïc Guitaut
parent 6d918c6307
commit c78211cf8d
5 changed files with 37 additions and 28 deletions

View File

@@ -202,13 +202,18 @@ module Service
attributes = class_name.attribute_names.map(&:to_sym)
default_values = {}
default_values = context[default_values_from].slice(*attributes) if default_values_from
contract = class_name.new(default_values.merge(context[:params].slice(*attributes)))
contract =
class_name.new(
**default_values.merge(context[:params].slice(*attributes)),
options: context[:options],
)
context[contract_name] = contract
context[result_key] = Context.build
if contract.invalid?
context[result_key].fail(errors: contract.errors, parameters: contract.raw_attributes)
context.fail!
end
contract.freeze
end
private

View File

@@ -8,12 +8,17 @@ class Service::ContractBase
delegate :slice, :merge, to: :to_hash
def [](key)
public_send(key)
def initialize(*args, options: nil, **kwargs)
@__options__ = options
super(*args, **kwargs)
end
def []=(key, value)
public_send("#{key}=", value)
def options
@__options__
end
def [](key)
public_send(key)
end
def to_hash