ratamin 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 657e9468e290eff1deeeb657db061a98dca992bece11887421737f1094bbfa28
4
- data.tar.gz: 2d0672f141d7cd9596ccd108e848a0fbd7418f77de46b3f67e6a2aa6a1efe7b9
3
+ metadata.gz: 02ee6e23e9d84b754a71528330d35e2e19337d1dc4e9dc2573c0ead727e6f196
4
+ data.tar.gz: cba72054dff87188c6c1764ff69ad78ecc0d11383138fa6068d5fb486016535a
5
5
  SHA512:
6
- metadata.gz: 93d38f02ff57591d942ed0f463ed5098a46e084a1270b0aadbdf6b1f3496d23e7a4ec5a30c95f6c6fec23baa92dbe63ee82a5763991d4b4be7ae8cbf4d7dba98
7
- data.tar.gz: 15cf1c96fd1193292b98ef73626ea02859ee34c5d6f565c612a93a3d3adddaa62e1b3796185dadb2caa185e7fff0eddd4c43eade57a3e49560163a42fa813acb
6
+ metadata.gz: 9516cf7d76cf5e85907cf6a4d5e0f2cee6d990b772259a7c86b970a47a1d5fd7d70e87bea8c544ec5b9d7ec8c382aa5bb0814f46665fee35b6ef027f006336ff
7
+ data.tar.gz: 9d33dc214b7353fb81d867598ffaa5eb100a7e748dd4f247e833637f7df469803530fd715fd145f58f0acd8ef0ebbb0bdb70aca86ada03fcfd22e2aa3940e01d
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: release-gem
3
+ description: Release a new version of the gem to RubyGems, update CHANGELOG.md, create a GitHub Release, and push a git tag. Use when the user wants to publish a new gem version.
4
+ argument-hint: [version]
5
+ ---
6
+
7
+ Release the gem. If $ARGUMENTS is provided, that is the new version number. Otherwise read the current version from `lib/ratamin/version.rb`.
8
+
9
+ Steps:
10
+
11
+ 1. **Confirm version**: Read `lib/ratamin/version.rb`. If $ARGUMENTS differs from the current version, update the file and commit the change.
12
+
13
+ 2. **Run tests**: `bundle exec rspec` — abort if any tests fail.
14
+
15
+ 3. **Update CHANGELOG.md**: Add a new section for this version at the top (below the `## [Unreleased]` header if present), using Keep a Changelog format:
16
+ ```
17
+ ## [X.Y.Z] - YYYY-MM-DD
18
+ ### Added / Changed / Fixed
19
+ - ...
20
+ ```
21
+ Ask the user what to put in the changelog if there is nothing obvious from recent commits. Commit the changelog update together with any version bump.
22
+
23
+ 4. **Build the gem**: `gem build ratamin.gemspec`
24
+
25
+ 5. **Push to RubyGems**: `gem push ratamin-X.Y.Z.gem`
26
+
27
+ 6. **Create git tag**: `git tag vX.Y.Z`
28
+
29
+ 7. **Push commits and tag**: `git push origin main --tags`
30
+
31
+ 8. **Create GitHub Release**: Extract the release notes for this version from CHANGELOG.md and run:
32
+ ```
33
+ gh release create vX.Y.Z --title "vX.Y.Z" --notes-file <(extracted notes)
34
+ ```
35
+
36
+ Report the RubyGems page and GitHub Release URL when done.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
1
8
  ## [Unreleased]
2
9
 
10
+ ## [0.2.0] - 2026-03-14
11
+
12
+ ### Added
13
+ - `has_ratamin` DSL on models to declare which columns to display and override labels/widths
14
+ - `Ratamin::Railtie` (opt-in via `require "ratamin/railtie"`) — injects `has_ratamin`/`Model.ratamin` into all AR models and `scope.ratamin` into `AR::Relation`
15
+ - Default sort order is now newest-first (descending primary key) when no explicit order is given
16
+
17
+ ### Fixed
18
+ - `has_ratamin` columns now inherit type and editability from the AR schema; explicitly passed options override the schema defaults
19
+ - `Model.ratamin` no longer causes `SystemStackError` when the Railtie is not loaded
20
+ - Forms where all columns are read-only no longer trap the user — `Esc` and `Enter` always work
21
+ - Pagination fallback order now uses a table-qualified `ORDER BY "table"."id"` to avoid ambiguous column errors on joined scopes
22
+
3
23
  ## [0.1.0] - 2026-03-14
4
24
 
5
- - Initial release
25
+ ### Added
26
+ - TUI admin console built on `ratatui_ruby` with table view and inline form editing
27
+ - `ArrayDataSource` for in-memory data with a duck-type `DataSource` protocol
28
+ - `ScopeDataSource` for ActiveRecord scopes with automatic column inference
29
+ - Pagination support for AR scopes (limit/offset with configurable `per_page`)
30
+ - `$EDITOR` integration for `:text` type fields (respects arguments in `$EDITOR`)
31
+ - Non-editable fields (`id`, `created_at`, `updated_at`) protected from editing
32
+ - Save failure handling — validation errors displayed inline in the form
33
+ - Dirty tracking — only changed fields are sent to `update_row`
34
+ - Zeitwerk autoloading
35
+ - RSpec test suite with in-memory SQLite for ActiveRecord integration tests
36
+ - GitHub Actions CI on Ruby 3.3, 3.4, and 4.0
37
+
38
+ [Unreleased]: https://github.com/onyxblade/ratamin/compare/v0.2.0...HEAD
39
+ [0.2.0]: https://github.com/onyxblade/ratamin/compare/v0.1.0...v0.2.0
40
+ [0.1.0]: https://github.com/onyxblade/ratamin/releases/tag/v0.1.0
data/README.md CHANGED
@@ -14,18 +14,47 @@ gem "ratamin"
14
14
 
15
15
  ## Usage
16
16
 
17
- ### With ActiveRecord
17
+ ### Rails integration (recommended)
18
+
19
+ Add the Railtie to an initializer to unlock `Model.ratamin` and `scope.ratamin` across your entire app:
20
+
21
+ ```ruby
22
+ # config/initializers/ratamin.rb
23
+ require "ratamin/railtie"
24
+ ```
25
+
26
+ Then define which columns to show in your model:
27
+
28
+ ```ruby
29
+ class User < ApplicationRecord
30
+ has_ratamin do
31
+ column :name, label: "Full Name", width: 20
32
+ column :email, width: 30
33
+ column :bio # type and editable inferred from schema
34
+ end
35
+ end
36
+ ```
37
+
38
+ Open the console and run:
39
+
40
+ ```ruby
41
+ User.ratamin # all records, newest first
42
+ User.where(role: "admin").ratamin # filtered scope
43
+ ```
44
+
45
+ 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.
46
+
47
+ Without the Railtie, `scope.ratamin` is unavailable. You can still call `User.ratamin` after manually including `Ratamin::ModelMixin` in the model.
48
+
49
+ ### Manual usage (without Railtie)
18
50
 
19
51
  ```ruby
20
52
  require "ratamin"
21
53
 
22
- # Edit all users
54
+ # Columns are inferred from the schema automatically
23
55
  Ratamin::App.new(Ratamin::ScopeDataSource.new(User.all)).run
24
56
 
25
- # Edit a filtered scope
26
- Ratamin::App.new(Ratamin::ScopeDataSource.new(User.where(role: "admin"))).run
27
-
28
- # Specify which columns to show
57
+ # Or specify columns explicitly
29
58
  columns = [
30
59
  Ratamin::Column.new(key: :name, label: "Name", width: 20),
31
60
  Ratamin::Column.new(key: :email, label: "Email", width: 30),
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ratamin
4
+ class ModelConfig
5
+ attr_reader :column_specs
6
+
7
+ def initialize
8
+ @column_specs = []
9
+ end
10
+
11
+ # Stores only the explicitly provided overrides; schema defaults are applied
12
+ # later by ScopeDataSource when it merges with AR column metadata.
13
+ def column(key, **overrides)
14
+ @column_specs << {key: key.to_sym, **overrides}
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ratamin
4
+ module ModelMixin
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ # Define column config for the TUI:
11
+ #
12
+ # class User < ApplicationRecord
13
+ # has_ratamin do
14
+ # column :name, label: "Full Name", width: 20
15
+ # column :email, width: 30
16
+ # end
17
+ # end
18
+ #
19
+ def has_ratamin(&block)
20
+ @ratamin_config = ModelConfig.new
21
+ @ratamin_config.instance_eval(&block)
22
+ end
23
+
24
+ def ratamin_config
25
+ @ratamin_config
26
+ end
27
+
28
+ # Open the TUI for this model (defaults to all records, newest first):
29
+ #
30
+ # User.ratamin
31
+ #
32
+ def ratamin
33
+ scope = all.order(arel_table[primary_key].desc)
34
+ App.new(ScopeDataSource.new(scope)).run
35
+ end
36
+ end
37
+ end
38
+
39
+ module RelationMixin
40
+ def ratamin
41
+ source = ScopeDataSource.new(self)
42
+ App.new(source).run
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ratamin"
4
+ require "rails"
5
+
6
+ module Ratamin
7
+ class Railtie < Rails::Railtie
8
+ initializer "ratamin.extend_active_record" do
9
+ ActiveSupport.on_load(:active_record) do
10
+ include Ratamin::ModelMixin
11
+ ActiveRecord::Relation.include(Ratamin::RelationMixin)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -77,7 +77,7 @@ module Ratamin
77
77
  def ordered_scope
78
78
  s = @scope.reset
79
79
  if s.order_values.empty?
80
- s.order(s.klass.arel_table[s.klass.primary_key])
80
+ s.order(s.klass.arel_table[s.klass.primary_key].desc)
81
81
  else
82
82
  s
83
83
  end
@@ -93,14 +93,26 @@ module Ratamin
93
93
 
94
94
  def infer_columns
95
95
  model = @scope.klass
96
- model.column_names.map do |name|
96
+ schema_defaults = build_schema_defaults(model)
97
+
98
+ if model.respond_to?(:ratamin_config) && (config = model.ratamin_config)
99
+ return config.column_specs.map do |spec|
100
+ Column.new(**schema_defaults.fetch(spec[:key], {}).merge(spec))
101
+ end
102
+ end
103
+
104
+ schema_defaults.values.map { |attrs| Column.new(**attrs) }
105
+ end
106
+
107
+ def build_schema_defaults(model)
108
+ model.column_names.each_with_object({}) do |name, hash|
97
109
  col = model.columns_hash[name]
98
- Column.new(
110
+ hash[name.to_sym] = {
99
111
  key: name.to_sym,
100
112
  type: map_ar_type(col.type),
101
113
  width: guess_width(name, col.type),
102
114
  editable: !READONLY_COLUMNS.include?(name)
103
- )
115
+ }
104
116
  end
105
117
  end
106
118
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ratamin
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratamin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - merely
@@ -45,6 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".claude/skills/release-gem/SKILL.md"
48
49
  - ".github/workflows/ci.yml"
49
50
  - ".gitmodules"
50
51
  - CHANGELOG.md
@@ -60,6 +61,9 @@ files:
60
61
  - lib/ratamin/editor_bridge.rb
61
62
  - lib/ratamin/form_state.rb
62
63
  - lib/ratamin/form_view.rb
64
+ - lib/ratamin/model_config.rb
65
+ - lib/ratamin/model_mixin.rb
66
+ - lib/ratamin/railtie.rb
63
67
  - lib/ratamin/scope_data_source.rb
64
68
  - lib/ratamin/table_view.rb
65
69
  - lib/ratamin/update_result.rb