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
94%
Does it follow best practices?
Impact
92%
1.33xAverage score across 35 eval scenarios
Passed
No known issues
Use this skill when writing specs for ROM Relations and Repositories in Hanami 2.x.
Follow these steps in order, treating each as a checkpoint:
Place it under spec/relations/ or spec/repos/:
# spec/repos/users_spec.rb
RSpec.describe MyApp::Repos::UserRepo, type: :repo do
let(:repo) { described_class.new }
it "creates and finds a user by email" do
user = repo.create(email: "alice@example.com", name: "Alice")
expect(user.id).not_to be_nil
found = repo.find_by_email("alice@example.com")
expect(found.name).to eq("Alice")
end
endRun RSpec and confirm the spec fails because the relation/repo method is unimplemented:
bundle exec rspec spec/repos/users_spec.rbWrite only the minimal ROM query or persistence logic to make the specs pass.
Verify all specs pass green:
bundle exec rspec spec/repos/users_spec.rbUse transactional rollback — ensure each test runs in isolation and rolls back its changes:
around do |example|
Hanami.app["db.rom"] do |rom|
rom.gateways[:default].transaction do |t|
example.run
t.rollback
end
end
endTest custom Relation query methods — assert on collections returned by custom filters:
it "returns active users" do
# user1 and user2 created during setup
active_users = relation.active.to_a
expect(active_users.length).to eq(1)
expect(active_users.first.email).to eq("alice@example.com")
endVerify Repository CRUD operations — verify custom read, write, and update methods:
it "updates a user" do
repo.update(user1.id, first_name: "Alicia")
user = repo.by_id(user1.id).one
expect(user.first_name).to eq("Alicia")
endTest expected edge cases — verify empty lists, missing tuples, and mismatch errors:
it "raises when user is not found" do
expect { repo.by_id(99999).one! }.to raise_error(ROM::TupleCountMismatchError)
endwhere/insert/update mechanics rather than your custom repository queries.before(:all) for database data setup, which operates outside individual test transaction boundaries.| Related Skill | When to chain |
|---|---|
| create-repository | Repository creation precedes spec implementation. |
| define-relation | Relation definitions are verified via custom specs. |
docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
scenario-29
scenario-30
scenario-31
scenario-32
scenario-33
scenario-34
scenario-35
skills
actions
build-json-api
create-action
handle-errors
validate-params
context
load-context
db
create-changeset
create-repository
define-relation
write-migration
dry-monads
handle-result-pattern
dry-rb
create-operation
create-validation-contract
providers
configure-providers
implement-di
review-security
routing
define-routes
slices
configure-slice
create-slice
extract-slice
review-slice-boundaries
test-slice