Changelog History
Page 2
-
v0.10.1 Changes
June 29, 2017π Fixed
- Preserve step notification listeners when calling a transaction after passing extra step arguments (jcmfernandes in #65)
-
v0.10.0 Changes
June 14, 2017π This release makes major changes to the dry-transaction API: transactions are now defined within your own class, support instance methods for defining or wrapping steps, and operation containers are now optional.
β Added
β Added
Dry::Transaction::Operation
convenience mixin. This gives easy access toRight
andLeft
result builders within your operation objects, and also enables dry-matcher's block-based result matching API for when the operations are called individually. (timriley in #58)class MyOperation include Dry::Transaction::Operation def call(input) Right(input) end end my_op = MyOperation.new my_op.("hello") do |m| m.success do |v| "Success: #{v} end m.failure do |v| "Failure: #{v}" end end # => "Success: hello"
π Changed
[BREAKING] Transactions are now defined within your own classes using a mixin & class-level API for step definitions (GustavoCaso & timriley in #58)
class CreateUser include Dry::Transaction(container: Container) step :process, with: "operations.process" step :validate, with: "operations.validate" step :persist, with: "operations.persist" end create_user = CreateUser.new create_user.call("name" => "Jane Doe")
Instance methods can wrap operations by calling
super
:```ruby class CreateUser include Dry::Transaction(container: Container) step :process, with: "operations.process" step :validate, with: "operations.validate" step :persist, with: "operations.persist" def process(input) adjusted_input = do_something_with(input) super(adjusted_input) end end ```
Substitute operations can be injected when initializing objects (helpful for testing):
```ruby create_user = CreateUser.new(process: substitute_process_operation) ```
Transactions can be defined without an operations container, using instance methods only.
class CreateUser include Dry::Transaction step :process step :validate def process(input) input = do_something_with(input) Right(input) end def validate(input) if input[:email].include?("@") Right(input) else Left(:not_valid) end end end
π [BREAKING] You can no longer extend existing transactions with
#prepend
,#append
,#insert
, or#remove
. Since transactions will now be instances of your own classes, with their own different behaviors, thereβs no predictable way to combine the behaviors of two different classes. If you need the ability to add or remove steps, you can create separate transactions for the different behaviours you need to offer, or build into your own transaction class a way to skip steps based on input or step arguments.π [BREAKING] Blocks in step definitions are no longer accepted. If you want to wrap a step with some local behavior, wrap it with an instance method (see above).
π§ [BREAKING] There is no longer an option for configuring the result matcher block API - we now use
Dry::Transaction::ResultMatcher
by default. If you want to provide your own matcher, you can do this by overriding#call
in your transaction classes and using your own matcher when a block is given.
-
v0.9.0 Changes
December 18, 2016β Added
Procs (or any callable objects) can be passed as a step's
with:
option instead of a container identifier string (AMHOL in #44)Dry.Transaction(container: MyContainer) do step :some_step, with: "operations.some_thing" step :another, with: -> input { # your code here } end
π Support for passing blocks to step adapters (am-kantox in #36)
Dry.Transaction(container: MyContainer) do my_custom_step :some_step do # this code is captured as a block and passed to the step adapter end end
π Changed
- Whole step object is passed to
StepFailure
upon failure, which provides more information to custom matchers (mrbongiolo in #35) #call
argument order for step operations is now#call(input, *args)
, not#call(*args, input)
(timriley in #48)Dry::Transaction::Sequence
renamed toDry::Transaction
(timriley in #49)
-
v0.8.0 Changes
July 06, 2016β Added
- Provide your own matcher object via a
matcher:
option passed toDry.Transaction
(timriley)
π Changed
- Match block API is now provided by
dry-matcher
gem (timriley) - Matching behaviour is clearer: match cases are run in order, the first match case βwinsβ and is executed, and all subsequent cases are ignored. This ensures a single, deterministic return value from the match block - the output of the single βwinningβ match case. (timriley)
- Provide your own matcher object via a
-
v0.7.0 Changes
June 06, 2016β Added
- π»
try
steps support a:raise
option, so a caught exception can be re-raised as a different (more domain-specific) exception (mrbongiolo)
π Fixed
- Add
#respond_to_missing?
toStepFailure
wrapper class so it can more faithfully represent the failure object it wraps (flash-gordon) - π Stop the DSL processing from conflicting with ActiveSupport's
Object#try
monkey-patch (joevandyk)
π Changed
- π Use dry-monads (e.g.
Dry::Monads::Either::Right
) instead of kleisli (Kleisli::Either::Right
) (flash-gordon)
- π»
-
v0.6.0 Changes
April 06, 2016β Added
- π Allow custom step adapters to be supplied via a container of adapters being passed as a
step_adapters:
option toDry.Transaction
(timriley) - Raise a meaningful error if a
step
step returns a non-Either
object (davidpelaez) - ## Internal
- π Change the step adapter API so more step-related information remains available at the time of the step being called (timriley)
- π Allow custom step adapters to be supplied via a container of adapters being passed as a
-
v0.5.0 Changes
March 16, 2016 -
v0.4.0 Changes
December 26, 2015 -
v0.3.2 Changes
November 13, 2015 -
v0.3.1 Changes
November 12, 2015