README.md in fluxo-0.2.1 vs README.md in fluxo-0.3.0

- old
+ new

@@ -28,48 +28,39 @@ end end ``` And then just use the opperation by calling: -``` +```ruby result = MyOperation.call result.success? # => true result.value # => :ok ``` -In order to execute an operation with parameters, you must first define list of attributes: +In order to execute an operation with parameters, you just need to pass them to the call method: ```ruby class MyOperation < Fluxo::Operation - attributes :param1, :param2 - def call!(param1:, param2:) Success(:ok) end end ``` -or use the shortcut for defining attributes: -```ruby -class MyOperation < Fluxo::Operation(:param1, :param2) - def call!(param1:, param2:) - Success(:ok) - end -end -``` - ### Operation Result The execution result of an operation is a `Fluxo::Result` object. There are three types of results: * `:ok`: the operation was successful * `:failure`: the operation failed * `:exception`: the operation raised an error Use the `Success` and `Failure` methods to create results accordingly. ```ruby -class AgeCheckOperation < Fluxo::Operation(:age) +class AgeCheckOperation < Fluxo::Operation + self.strict = false # By default, operations are strict. You must it to catch errors and use on_error hook. + def call!(age:) age >= 18 ? Success('ok') : Failure('too young') end end @@ -95,11 +86,11 @@ ``` You can also define multiple callbacks for the opportunity result. The callbacks are executed in the order they were defined. You can filter which callbacks are executed by specifying an identifier to the `Success(id) { }` or `Failure(id) { }` methods along with its value as a block. ```ruby -class AgeCategoriesOperation < Fluxo::Operation(:age) +class AgeCategoriesOperation < Fluxo::Operation def call!(age:) case age when 0..14 Failure(:child) { "Sorry, you are too young" } when 15..17 @@ -126,11 +117,11 @@ ### Operation Flow Once things become more complex, you can use can define a `flow` with a list of steps to be executed: ```ruby -class ArithmeticOperation < Fluxo::Operation(:num) +class ArithmeticOperation < Fluxo::Operation flow :normalize, :plus_one, :double, :square, :wrap def normalize(num:) Success(num: num.to_i) end @@ -157,16 +148,14 @@ ArithmeticOperation.call(num: 1) \ .on_success { |result| puts "Result: #{result.value}" } # Result: 16 ``` -Notice that the value of each step is passed to the next step as an argument. And the last step is always the result of the operation. +Notice that the value of each step is passed to the next step as an argument. You can include more transient attributes during the flow execution. Step result with object different of a Hash will be ignored. And the last step is always the result of the operation. -By default you can only pass defined attributes to the steps. You may want to pass transient attributes to the steps. You can do this by specifying a `transient_attributes` option to the operation class: - ```ruby -class CreateUserOperation < Fluxo::Operation(:name, :age) +class CreateUserOperation < Fluxo::Operation flow :build, :save def build(name:, age:) user = User.new(name: name, age: age) Success(user: user) @@ -178,46 +167,30 @@ Success(user: user) end end ``` -This is useful to make the flow data transparent to the operation. But you can also disable this by setting the `strict_transient_attributes` option to `false` under the Operation class or the global configuration. - -```ruby -class CreateUserOperation < Fluxo::Operation(:name, :age) - self.strict_transient_attributes = false - # ... -end -# or globally -Fluxo.config do |config| - config.strict_attributes = false - config.strict_transient_attributes = false -end -# or even -Fluxo.config.strict_transient_attributes = false -``` - ### Operation Groups Another very useful feature of Fluxo is the ability to group operations steps. Imagine that you want to execute a bunch of operations in a single transaction. You can do this by defining a the group method and specifying the steps to be executed in the group. ```ruby -class CreateUserOperation < Fluxo::Operation(:name, :email) - transient_attributes :user, :profile - - flow :build, {transaction: %i[save_user save_profile]}, :enqueue_job - +class ApplicationOperation < Fluxo::Operation private def transaction(**kwargs, &block) ActiveRecord::Base.transaction do result = block.call(**kwargs) raise(ActiveRecord::Rollback) unless result.success? end result end +end +class CreateUserOperation < ApplicationOperation + flow :build, {transaction: %i[save_user save_profile]}, :enqueue_job + def build(name:, email:) user = User.new(name: name, email: email) Success(user: user) end @@ -243,11 +216,11 @@ ### Operation Validation If you have the `ActiveModel` gem installed, you can use the `validations` method to define validations on the operation. ```ruby -class SubscribeOperation < Fluxo::Operation(:name, :email) +class SubscribeOperation < Fluxo::Operation validations do validates :name, presence: true validates :email, presence: true, format: { with: /\A[^@]+@[^@]+\z/ } end @@ -260,23 +233,23 @@ ### Operations Composition To promote single responsibility principle, Fluxo allows compose a complex operation flow by combining other operations. ```ruby -class DoubleOperation < Fluxo::Operation(:num) +class DoubleOperation < Fluxo::Operation def call!(num:) Success(num: num * 2) end end -class SquareOperation < Fluxo::Operation(:num) +class SquareOperation < Fluxo::Operation def call!(num:) Success(num: num * 2) end end -class ArithmeticOperation < Fluxo::Operation(:num) +class ArithmeticOperation < Fluxo::Operation flow :normalize, :double, :square def normalize(num:) Success(num: num.to_i) end @@ -292,14 +265,13 @@ ``` ### Configuration ```ruby -Fluxo.config do |config| +Fluxo.configure do |config| config.wrap_falsey_result = false config.wrap_truthy_result = false - config.strict_attributes = true - config.strict_transient_attributes = true + config.strict = true config.error_handlers << ->(result) { Honeybadger.notify(result.value) } end ```