-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add extension for ROM transactions #15
Conversation
8656266
to
4117807
Compare
A quick note about being able to provide options to the @timriley, @solnic, please, just tell me if I'm missing something. |
ce38bc3
to
5a96ae4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Just a couple very minor things here but otherwise let's get this in :)
Let's make sure we get the issue with the #transaction
arguments properly looked at, too, but AFAICT that shouldn't prevent this from being merged in the meantime?
5a96ae4
to
511ad90
Compare
We add a `Dry::Operation::Extensions::ROM` module that, when included, gives access to a `#transaction` method. This method wraps the yielded steps in a ROM [1] transaction, rolling back in case one of them returns a failure. We lean on a new `Dry::Operation#intercepting_failure` method, which allows running a callback before the failure is re-thrown again to be managed by the wrapping `#steps` call. Besides providing clarity, this method will be reused by future extensions. The extension expects the including class to define a `#rom` method giving access to the ROM container. ```ruby class MyOperation < Dry::Operation include Dry::Operation::Extensions::ROM attr_reader :rom def initialize(rom:) @rom = rom end def call(input) attrs = step validate(input) user = transaction do new_user = step persist(attrs) step assign_initial_role(new_user) new_user end step notify(user) user end # ... end ``` The extension uses the `:default` gateway by default, but it can be changed both at include time with `include Dry::Operation::Extensions::ROM[gateway: :my_gateway]`, and at runtime with `#transaction(gateway: :my_gateway)`. This commit also establishes the dry-operation's convention for database transactions. Instead of wrapping the whole flow, we require the user to be conscious of the transaction boundaries (not including, e.g., external requests or notifications). That encourages using individual operations when thinking about composition instead of the whole flow. [1] - https://rom-rb.org
c19755d
to
bd18280
Compare
We add a
Dry::Operation::Extensions::ROM
module that, when included, gives access to a#transaction
method. This method wraps the yielded steps in a ROM transaction, rolling back in case one of them returns a failure.We lean on a new
Dry::Operation#intercepting_failure
method, which allows running a callback before the failure is re-thrown again to be managed by the wrapping#steps
call. Besides providing clarity, this method will be reused by future extensions.The extension expects the including class to define a
#rom
method giving access to the ROM container.The extension uses the
:default
gateway by default, but it can be changed both at include time withinclude Dry::Operation::Extensions::ROM[gateway: :my_gateway]
, and at runtime with#transaction(gateway: :my_gateway)
.This commit also establishes the dry-operation's convention for database transactions. Instead of wrapping the whole flow, we require the user to be conscious of the transaction boundaries (not including, e.g., external requests or notifications). That encourages using individual operations when thinking about composition instead of the whole flow.