Project

ratamin

0.0
No release in over 3 years
A terminal UI for browsing and editing ActiveRecord scopes, built on ratatui_ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

Ratamin

A TUI admin console for ActiveRecord, built on ratatui_ruby.

Give it a scope, get a navigable table with inline editing and $EDITOR support for long text.

Installation

Add to your Gemfile:

gem "ratamin"

Usage

Rails integration (automatic)

In a Rails app, Model.ratamin and scope.ratamin are available automatically — no configuration needed. Just add the gem and define which columns to show in your model:

class User < ApplicationRecord
  has_ratamin do
    column :name, label: "Full Name", width: 20
    column :email, width: 30
    column :bio                        # type and editable inferred from schema
  end
end

Open the console and run:

User.ratamin                           # all records, newest first
User.where(role: "admin").ratamin      # filtered scope

Column type (:text vs :string) and editability (id, created_at, updated_at are read-only by default) are inferred from the schema. Any option explicitly passed to column overrides the inferred default.

To opt out of the Rails integration, use require: false in your Gemfile and require "ratamin" manually — scope.ratamin will then be unavailable, but the core API still works.

Manual usage (without Railtie)

require "ratamin"

# Columns are inferred from the schema automatically
Ratamin::App.new(Ratamin::ScopeDataSource.new(User.all)).run

# Or specify columns explicitly
columns = [
  Ratamin::Column.new(key: :name, label: "Name", width: 20),
  Ratamin::Column.new(key: :email, label: "Email", width: 30),
  Ratamin::Column.new(key: :bio, label: "Bio", type: :text),
]
Ratamin::App.new(Ratamin::ScopeDataSource.new(User.all, columns: columns)).run

Without ActiveRecord

require "ratamin"

columns = [
  Ratamin::Column.new(key: :name, width: 20),
  Ratamin::Column.new(key: :email, width: 30),
]

rows = [
  { name: "Alice", email: "alice@example.com" },
  { name: "Bob",   email: "bob@example.com" },
]

ds = Ratamin::ArrayDataSource.new(columns: columns, rows: rows)
Ratamin::App.new(ds).run

Keybindings

Table view

Key Action
j / Down Next row
k / Up Previous row
g First row
G Last row
l / Enter Edit selected record
r Reload data
PageDown Next page
PageUp Previous page
Esc / q Quit

Form view — select mode

Key Action
j / Down Next field
k / Up Previous field
Tab Next field
Shift+Tab Previous field
l / Enter Edit field
Ctrl+E Open $EDITOR
s Save
h / Esc Cancel (back to table)

Form view — edit mode

Key Action
Enter Confirm and move to next field
Esc Discard changes and exit edit
Ctrl+E Open $EDITOR
Left / Right Move cursor
Home / End Jump to start/end
Backspace / Delete Delete character

Architecture

Ratamin separates data, state, and rendering:

  • DataSource — duck-type protocol (#columns, #rows, #update_row, #reload!)
    • ArrayDataSource — in-memory arrays
    • ScopeDataSource — wraps an ActiveRecord scope
  • State — pure Ruby, no TUI dependency, fully unit-testable
    • FormState — field values, cursor, text editing, validation errors
  • Views — thin renderers that read from state objects
    • TableView — record list with selection
    • FormView — field-by-field editor

Column types

Type Behavior
:string (default) Inline text editing
:text Truncated in table, opens $EDITOR for editing

Development

bin/setup
bundle exec rspec

License

MIT