Project

handleit

0.0
No release in over a year
Handleit - promise like way of handling logic execution with ability of chaining handlers like in js promise, plus some useful additions like guard and rollback
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

Handleit

Gem GitHub last commit Gem

Problem:

  • Want to have JS Promise-like way of handling logic execution, with ability to chain handlers, plus useful additions like guard adn rollback?

Solution:

  • Use wrap execution class within Handle.it block and chain handlers in the Promise manner

Notes:

  • Could be good matching in rails controllers, when it is important to have declarative way of handling execution.
  • Use guard feature with 'it' method args, like:
def valid?
  false
end

Handle.it(when: valid?, not_valid_error: 'User not found')
  .with { |r| redirect_to wellcome(user), notice: 'Welcome!' }
  .on_fail { |e| pp e.message }

=> 'User not found'

if valid returns 'false', it goes to on_fail block with specific error message

  • Use rollback feature with 'with' method args, like:
Handle.it { "Ruby rules" }
  .with(on_fail: :rollback) { |res| res.upcase.split.unknow_method_call }
  .result

=> 'Ruby rules'

if you want to have last successful result neglecting errors.

Install

gem install handleit

Rails

gem 'handleit', require: %w[handle]

Examples

class UsersController < ApplicationController
  def auth
    Handle.it(when: valid?, not_valid_error: 'User not found') do
      AuthService.authenticate!
    end 
      .with { |res| redirect_to wellcome(user), notice: 'Welcome!'}
      .on_fail { |e| redirect_to login(user), notice: "Authentication error: #{e.message}" }
  end
  
  def valid?
    # some validation logic
  end
end
# ...

class Service
  class << self
    def some_cool_logic
      "some_cool_string"
    end
    
    def error_raiser
      raise StandardError
    end
  end
end
# ...

# Handle.it with
pry(main)> Handle.it { Service.some_cool_logic }
pry(main)>  .with { |res| res + " bla" }
pry(main)>  .with { |res| pp res }
pry(main)>  .on_fail { |e| pp e }
pry(main)>  .result

=> "some_cool_string bla"

# Handle.it shortcut methods
pry(main)> H.it { Service.some_cool_logic }
pry(main)>  .> { |res| res + " bla" }
pry(main)>  .> { |res| pp res }
pry(main)>  .e { |e| pp e }
pry(main)>  .<=

=> "some_cool_string bla"

# Handle.it on_fail
pry(main)> Handle.it { Service.error_raiser }
pry(main)>  .with { |res| res + " bla" }
pry(main)>  .with { |res| pp res }
pry(main)>  .on_fail { |e| pp e }

=> #<StandardError: StandardError>

# pipelining result
pry(main)> Handle.it { "Elixir rocks" }
pry(main)>  .with { |res| res.size - 1 }
pry(main)>  .with { |res| res.upcase.split.first }
pry(main)>  .result

=> 5

# rollback result instead of sending it into on_fail block, so it returns latest successful
pry(main)> Handle.it { "Elixir rocks" }
pry(main)>  .with { |res| res.size - 1 }
pry(main)>  .with(on_fail: :rollback) { |res| res.upcase.split.unknow_method_call }
pry(main)>  .on_fail { |e| pp e }
pry(main)>  .result

=> 11