CtrlK
BlogDocsLog inGet started
Tessl Logo

igmarin/hanakai-yaku

Curated library of atomic AI agent skills for Hanami, dry-rb, and ROM Ruby development. Covers actions, slices, repositories, relations, changesets, providers, DI, operations, TDD, CLI, views, routing, and validation. Shared Ruby process skills have moved to ruby-core-skills. Uses Markdown + Front-matter architecture.

92

1.33x
Quality

94%

Does it follow best practices?

Impact

92%

1.33x

Average score across 35 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

RAILS_COMPARISON.mdskills/dry-monads/handle-result-pattern/

Rails Exception Pattern vs Hanami Result Pattern

This document compares traditional Rails ActiveRecord exception/save patterns against Hanami's monadic Result patterns.


Comparison Table

Rails (ActiveRecord)Hanami 2.x (dry-monads Result Pattern)
User.create!(attrs) (raises on failure)create_user.call(attrs)Success(user) or Failure(error)
ActiveRecord::RecordInvalid exceptionsFailure({ code: :validation_failed, errors: ... }) (as values)
rescue_from ActiveRecord::RecordNotFoundPattern match Failure in Action and halt 404
if user.save; ...; else; ...; endcase result; in Success(v); ...; in Failure(e); ...; end
Service objects (custom class with raise)dry-monads service objects returning Success/Failure
before_action for sequential stepsDo notation (yield) for sequencing multiple operations

Pattern Example

Rails Exception Style

# Rails Controller
def create
  @user = User.create!(user_params)
  deliver_welcome_email(@user)
  render json: @user, status: :created
rescue ActiveRecord::RecordInvalid => e
  render json: { errors: e.record.errors }, status: :unprocessable_entity
end

Hanami Monadic Style

# Hanami Action
def handle(request, response)
  result = create_user.call(request.params[:user])
  
  case result
  in Success(user)
    response.status = 201
    response.body = UserSerializer.new(user).to_json
  in Failure(error_payload)
    response.status = 422
    response.body = { error: error_payload }.to_json
  end
end

skills

dry-monads

handle-result-pattern

README.md

tile.json