inline_forms 8.1.40 → 8.1.42
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 +4 -4
- data/.forgejo/workflows/full-gate.yml +4 -2
- data/.gitignore +6 -2
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +44 -0
- data/CLAUDE.md +68 -0
- data/Gemfile +4 -0
- data/Rakefile +52 -11
- data/app/controllers/inline_forms_controller.rb +15 -0
- data/app/views/inline_forms/_new.html.erb +4 -1
- data/app/views/inline_forms/_pending_migration_row.html.erb +15 -0
- data/app/views/inline_forms/_show.html.erb +4 -1
- data/app/views/inline_forms/field_pending.html.erb +10 -0
- data/lib/generators/inline_forms_addto/USAGE +31 -0
- data/lib/generators/inline_forms_addto_generator.rb +198 -26
- data/lib/inline_forms/attribute_list.rb +191 -0
- data/lib/inline_forms/gem_files.rb +26 -0
- data/lib/inline_forms/schema_apply.rb +85 -0
- data/lib/inline_forms/schema_intent.rb +76 -0
- data/lib/inline_forms/schema_label.rb +65 -0
- data/lib/inline_forms/schema_preview.rb +135 -0
- data/lib/inline_forms/version.rb +1 -1
- data/lib/inline_forms.rb +86 -0
- data/lib/locales/inline_forms.en.yml +2 -0
- data/lib/locales/inline_forms.nl.yml +2 -0
- data/test/attribute_list_test.rb +165 -0
- data/test/dummy/app/controllers/gizmos_controller.rb +4 -0
- data/test/dummy/app/models/gizmo.rb +25 -0
- data/test/dummy/config/application.rb +3 -0
- data/test/dummy/config/routes.rb +9 -0
- data/test/inline_forms_addto_generator_test.rb +220 -0
- data/test/integration/pending_migration_gate_test.rb +75 -0
- data/test/integration/schema_batch_pipeline_test.rb +189 -0
- data/test/integration/schema_edit_test.rb +141 -0
- data/test/integration/schema_preview_test.rb +65 -0
- data/test/integration_test_helper.rb +41 -0
- data/test/schema_apply_test.rb +73 -0
- data/test/schema_intent_test.rb +53 -0
- data/test/schema_label_test.rb +61 -0
- metadata +29 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 11df5d86221aad276d5bf2d4878702ce6651b595bd84f4911534922da817e07a
|
|
4
|
+
data.tar.gz: 14ac9ad9346af55d6573926f46f8fd907bf7d86e9eb695887d45e9abd5f67e58
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f5b578c9c304f90509dc7fc1fe5a226b6f1b954eb11a451053f5107c474278caecc7fcf456f339794b34014078c38205a30ad786acd426d269ef6cff9096614
|
|
7
|
+
data.tar.gz: af1a4a4a228b4b3be79e5d71ab0b2ef6f2f02fb662032bad0b9ba40b285de548abbcb31c8adb501e990dd0d02ac3532819e3acee09334cc83f4899d8f42f8fc7
|
|
@@ -33,17 +33,19 @@ jobs:
|
|
|
33
33
|
token: ${{ secrets.VALIDATION_HINTS }}
|
|
34
34
|
path: validation_hints
|
|
35
35
|
|
|
36
|
-
- name: Build the
|
|
36
|
+
- name: Build the four gems
|
|
37
37
|
run: |
|
|
38
38
|
cd validation_hints && gem build validation_hints.gemspec && cd ..
|
|
39
39
|
cd inline_forms && gem build inline_forms.gemspec && gem build inline_forms_installer.gemspec
|
|
40
|
+
cd inline_forms_schema_edit && gem build inline_forms_schema_edit.gemspec
|
|
40
41
|
|
|
41
42
|
- name: Install built gems
|
|
42
43
|
run: |
|
|
43
44
|
gem install --no-document \
|
|
44
45
|
validation_hints/validation_hints-*.gem \
|
|
45
46
|
inline_forms/inline_forms-*.gem \
|
|
46
|
-
inline_forms/inline_forms_installer-*.gem
|
|
47
|
+
inline_forms/inline_forms_installer-*.gem \
|
|
48
|
+
inline_forms/inline_forms_schema_edit/inline_forms_schema_edit-*.gem
|
|
47
49
|
|
|
48
50
|
# The installer git-inits the generated app and makes an initial commit
|
|
49
51
|
# (installer_core.rb: `git add .` + `git commit`); a bare container has
|
data/.gitignore
CHANGED
|
@@ -21,10 +21,14 @@ pkg
|
|
|
21
21
|
# Builds
|
|
22
22
|
*.gem
|
|
23
23
|
|
|
24
|
+
# Scratch / local notes and secrets (e.g. stuff/forgejo-token). Kept in-repo
|
|
25
|
+
# .gitignore on purpose: the global excludes file that also ignores this is
|
|
26
|
+
# per-machine and is absent on the release box, which let stuff/ leak into
|
|
27
|
+
# `gem build`. Do not rely on the global ignore alone.
|
|
28
|
+
stuff/
|
|
29
|
+
|
|
24
30
|
Gemfile.lock
|
|
25
31
|
|
|
26
|
-
# Local notes / analysis (not tracked)
|
|
27
|
-
stuff/
|
|
28
32
|
|
|
29
33
|
|
|
30
34
|
# test/dummy runtime artifacts (in-memory DB; only logs/tmp may appear)
|
data/.rubocop.yml
CHANGED
|
@@ -14,6 +14,7 @@ AllCops:
|
|
|
14
14
|
TargetRubyVersion: 3.3
|
|
15
15
|
Exclude:
|
|
16
16
|
- "pkg/**/*"
|
|
17
|
+
- "inline_forms_schema_edit/pkg/**/*"
|
|
17
18
|
- "vendor/**/*"
|
|
18
19
|
- "archived/**/*" # frozen historical code; linting defeats the purpose
|
|
19
20
|
- "lib/installer_templates/**/*" # templates for *generated apps*, not engine style
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,50 @@ All notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [8.1.42] - 2026-07-22
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`gem build` no longer packages the `stuff/` scratch dir (and its secrets).**
|
|
12
|
+
`InlineFormsGemFiles.gem_files` sweeps untracked files, so it depended on
|
|
13
|
+
`stuff/` being git-ignored. That ignore lived only in the per-machine global
|
|
14
|
+
excludes file, which is absent on the release box — so `stuff/forgejo-token`
|
|
15
|
+
(mode 0600) leaked into the file list and `gem build` died with `Errno::EACCES`.
|
|
16
|
+
`stuff/` is now excluded in `gem_files` itself, independent of any ignore
|
|
17
|
+
config, and re-added to the repo `.gitignore` as a second line of defense.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Schema-change GUI extracted into its own gem** (`inline_forms_schema_edit`,
|
|
22
|
+
same repo, own gemspec; phase 0 of
|
|
23
|
+
`stuff/2026-07-11-schema-gui-gem-and-automated-pipeline-plan.md`).
|
|
24
|
+
`InlineForms::SchemaController`, its views and the `inline_forms_schema`
|
|
25
|
+
layout move out of the engine; the staging services (`SchemaIntent`,
|
|
26
|
+
`SchemaPreview`, `SchemaApply`, `SchemaLabel`) stay. The installer gains a
|
|
27
|
+
`--schema-edit` flag (default off, implied by `--example`) that adds the gem
|
|
28
|
+
to the generated Gemfile and wires the schema routes + "+ field" nav link;
|
|
29
|
+
apps created without it ship no schema-GUI surface at all.
|
|
30
|
+
|
|
31
|
+
## [8.1.41] - 2026-07-11
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **`inline_forms_addto` hardened** (see `stuff/2026-07-11-add-scalar-attribute-to-existing-model.md`). Adding a field to an existing model is now safer:
|
|
36
|
+
- **Smarter row placement.** New `inline_forms_attribute_list` rows land above the trailing metadata block (the first `:info` / `created_at` / `updated_at` row, and a `:header` directly above it) instead of at the very end, so an editable field no longer drops into the read-only info section. New `--before=ATTR` / `--after=ATTR` options place the row explicitly (warn + fall back to the default when the anchor is missing).
|
|
37
|
+
- **Robust model rewriting.** The greedy `]…end` regex is replaced by a bracket-depth scan from `@inline_forms_attribute_list ||= [` to its matching `]`, which survives `].freeze`, trailing comments, methods defined after the list, and nested `[ ]` in choice rows.
|
|
38
|
+
- **Value-bearing elements.** Choice elements (`dropdown_with_values`, `dropdown_with_integers`, `dropdown_with_values_with_stars`, `radio_button`, `check_box`, `scale_with_integers`, `scale_with_values`) now emit a placeholder `{ 1 => 'one', 2 => 'two' }` values hash and a warning instead of a bare 2-element row that raised at show time.
|
|
39
|
+
- **Collision-free migration timestamps.** Migration filenames use `max(now, highest_existing + 1)` so back-to-back runs (or a run right after another generator in the same second) never collide.
|
|
40
|
+
- **"Run db:migrate" reminder** printed after generation, since the attribute_list row is written immediately but its column only exists after migrating.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- Example app now exercises `inline_forms_addto` end to end: the installer adds `Apartment#internal_note` via `rails g inline_forms_addto` + `db:migrate`, and `example_app_apartment_addto_field_test.rb` asserts the column migrated, the row renders on the stock show panel, and an inline update round-trips.
|
|
45
|
+
- Generator unit tests for the above (smart/explicit placement, `].freeze` + trailing-method robustness, value-bearing placeholder, timestamp uniqueness, and applying the generated migration to an in-memory sqlite DB).
|
|
46
|
+
|
|
47
|
+
### Lockstep
|
|
48
|
+
|
|
49
|
+
- validation_hints 8.1.41, inline_forms_installer 8.1.41.
|
|
50
|
+
|
|
7
51
|
## [8.1.40] - 2026-07-10
|
|
8
52
|
|
|
9
53
|
### Added
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# CLAUDE.md — inline_forms
|
|
2
|
+
|
|
3
|
+
Instructions for any work in the inline_forms repo (`/home/code/inline_forms`).
|
|
4
|
+
These apply to all work here and take precedence over global defaults where they
|
|
5
|
+
conflict. Consolidated from the former `stuff/prompt/workflow.md` and
|
|
6
|
+
`stuff/prompt/test-the-example-app.md`.
|
|
7
|
+
|
|
8
|
+
## Workflow after any significant change
|
|
9
|
+
|
|
10
|
+
1. Run the full example-app test (see **Testing the example app** below). Keep
|
|
11
|
+
improving until all tests succeed.
|
|
12
|
+
2. Bump the **patch** version. Stay in the **8.1** line until further notice.
|
|
13
|
+
Never bump the minor version — even for big or breaking changes.
|
|
14
|
+
- Change the version in **all four gems** so they stay in lockstep, always,
|
|
15
|
+
even if nothing changed in some of them:
|
|
16
|
+
`validation_hints`, `inline_forms`, `inline_forms_installer`, and
|
|
17
|
+
`inline_forms_schema_edit` (in this repo under `inline_forms_schema_edit/`).
|
|
18
|
+
3. Update the Changelog of all four gems.
|
|
19
|
+
4. Commit everything.
|
|
20
|
+
5. After committing, push to the `forgejo` remote
|
|
21
|
+
(`ssh://forgejo@dev02:2222/ace/...`) in **both repos** (inline_forms and
|
|
22
|
+
validation_hints) so every commit runs through CI (Forgejo Actions on dev02).
|
|
23
|
+
- Check the run at http://dev02:3300/ace/inline_forms/actions and fix
|
|
24
|
+
failures.
|
|
25
|
+
6. Never push to `origin` (GitHub). Only Ace pushes there, and GitHub must not
|
|
26
|
+
run anything (no `.github/workflows`).
|
|
27
|
+
|
|
28
|
+
## Testing the example app
|
|
29
|
+
|
|
30
|
+
Goal: build the current gem, install it into `/home/code/testInline`, recreate
|
|
31
|
+
`MyApp` from scratch using `--example`, and verify it with Rails tests.
|
|
32
|
+
|
|
33
|
+
Do all steps end-to-end without asking for confirmation unless a command fails.
|
|
34
|
+
|
|
35
|
+
### Steps
|
|
36
|
+
|
|
37
|
+
1. In `/home/code/inline_forms`:
|
|
38
|
+
- Ensure the latest code is used.
|
|
39
|
+
- Run: `rvm use .`
|
|
40
|
+
- Build gems:
|
|
41
|
+
`gem build inline_forms.gemspec && gem build inline_forms_installer.gemspec && (cd inline_forms_schema_edit && gem build inline_forms_schema_edit.gemspec)`
|
|
42
|
+
- Confirm the built file names/versions
|
|
43
|
+
(`inline_forms-<version>.gem`, `inline_forms_installer-<version>.gem`,
|
|
44
|
+
`inline_forms_schema_edit/inline_forms_schema_edit-<version>.gem`).
|
|
45
|
+
|
|
46
|
+
2. In `/home/code/testInline`:
|
|
47
|
+
- Remove the old app if present: `/home/code/testInline/MyApp`
|
|
48
|
+
- Run: `rvm use .`
|
|
49
|
+
- Install the freshly built gems from
|
|
50
|
+
`/home/code/inline_forms/inline_forms-<version>.gem`,
|
|
51
|
+
`inline_forms_installer-<version>.gem`, and
|
|
52
|
+
`inline_forms_schema_edit/inline_forms_schema_edit-<version>.gem`.
|
|
53
|
+
|
|
54
|
+
3. Still in `/home/code/testInline`:
|
|
55
|
+
- Generate a fresh example app:
|
|
56
|
+
`inline_forms create MyApp -d sqlite --example`
|
|
57
|
+
|
|
58
|
+
4. In `/home/code/testInline/MyApp`:
|
|
59
|
+
- Run: `rvm use .`
|
|
60
|
+
- Run verification: `rails test`
|
|
61
|
+
|
|
62
|
+
### Output requirements
|
|
63
|
+
|
|
64
|
+
- Briefly report each phase result (build, install, app generation, test run).
|
|
65
|
+
- Include the exact commands run.
|
|
66
|
+
- Include the test summary (runs/assertions/failures/errors/skips).
|
|
67
|
+
- If anything fails, stop at the failing step and include the exact error and
|
|
68
|
+
the next corrective command you recommend.
|
data/Gemfile
CHANGED
|
@@ -13,6 +13,10 @@ group :test do
|
|
|
13
13
|
gem "will_paginate", "~> 4.0"
|
|
14
14
|
gem "paper_trail", "~> 17.0"
|
|
15
15
|
gem "turbo-rails"
|
|
16
|
+
# The schema-GUI engine gem (same repo, own gemspec). Test group so the
|
|
17
|
+
# dummy app's `Bundler.require(*Rails.groups)` loads it and the engine's
|
|
18
|
+
# schema_edit integration tests exercise the extracted controller/views.
|
|
19
|
+
gem "inline_forms_schema_edit", path: "inline_forms_schema_edit"
|
|
16
20
|
end
|
|
17
21
|
|
|
18
22
|
group :development, :test do
|
data/Rakefile
CHANGED
|
@@ -7,11 +7,18 @@ namespace :installer do
|
|
|
7
7
|
Bundler::GemHelper.install_tasks name: "inline_forms_installer"
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
namespace :schema_edit do
|
|
11
|
+
# The schema-GUI gem lives in its own subdirectory (own gemspec, own pkg/).
|
|
12
|
+
Bundler::GemHelper.install_tasks dir: File.expand_path("inline_forms_schema_edit", __dir__),
|
|
13
|
+
name: "inline_forms_schema_edit"
|
|
14
|
+
end
|
|
15
|
+
|
|
10
16
|
def inline_forms_pkg_gems
|
|
11
|
-
pkg = File.expand_path("pkg", __dir__)
|
|
12
17
|
version = InlineForms::VERSION
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
{ "inline_forms" => "pkg",
|
|
19
|
+
"inline_forms_installer" => "pkg",
|
|
20
|
+
"inline_forms_schema_edit" => "inline_forms_schema_edit/pkg" }.map do |name, pkg|
|
|
21
|
+
path = File.expand_path(File.join(pkg, "#{name}-#{version}.gem"), __dir__)
|
|
15
22
|
raise "Missing #{path}. Run rake build:all first." unless File.file?(path)
|
|
16
23
|
path
|
|
17
24
|
end
|
|
@@ -25,8 +32,8 @@ def validation_hints_pkg_gem
|
|
|
25
32
|
].find { |path| File.file?(path) }
|
|
26
33
|
end
|
|
27
34
|
|
|
28
|
-
desc "Build
|
|
29
|
-
task "build:all" => [ "build", "installer:build" ]
|
|
35
|
+
desc "Build inline_forms, inline_forms_installer and inline_forms_schema_edit"
|
|
36
|
+
task "build:all" => [ "build", "installer:build", "schema_edit:build" ]
|
|
30
37
|
|
|
31
38
|
desc "Install freshly built gems from pkg/ into the current gemset (required before inline_forms create)"
|
|
32
39
|
task "install:local" => [ "build:all" ] do
|
|
@@ -38,16 +45,50 @@ task "install:local" => [ "build:all" ] do
|
|
|
38
45
|
puts "Verify: inline_forms --version 2>/dev/null || gem which inline_forms_installer"
|
|
39
46
|
end
|
|
40
47
|
|
|
41
|
-
# Release inline_forms + inline_forms_installer
|
|
42
|
-
# Does not run inline_forms create,
|
|
43
|
-
#
|
|
44
|
-
|
|
48
|
+
# Release inline_forms + inline_forms_installer + inline_forms_schema_edit
|
|
49
|
+
# (build, git tag/push, RubyGems push). Does not run inline_forms create,
|
|
50
|
+
# MyApp, or tests. validation_hints is a separate repo:
|
|
51
|
+
# cd ../validation_hints && rake release (same version number).
|
|
52
|
+
# Release git-push ALWAYS targets `origin` (GitHub) only.
|
|
53
|
+
#
|
|
54
|
+
# Do NOT use Bundler's stock `release:source_control_push`: it pushes to the
|
|
55
|
+
# CURRENT BRANCH's tracking remote (`git config branch.<branch>.remote`).
|
|
56
|
+
# Feature branches in this repo track `forgejo` (dev02) because that's where
|
|
57
|
+
# CI runs, so a release cut from a feature branch would push the release commit
|
|
58
|
+
# and version tag to forgejo instead of GitHub. `origin` is the only place
|
|
59
|
+
# release commits/tags belong; `forgejo` is CI-only. This task is also
|
|
60
|
+
# idempotent on the tag, so a re-run after a failed push still lands the tag on
|
|
61
|
+
# origin (Bundler's version skips entirely once the tag exists locally).
|
|
62
|
+
# Also override the bare `release` task (from install_tasks above) so a stray
|
|
63
|
+
# `rake release` can't push to a feature branch's forgejo tracking remote
|
|
64
|
+
# either. The intended entry point is `release:all`, but this closes the
|
|
65
|
+
# footgun on both.
|
|
66
|
+
Rake::Task["release"].clear if Rake::Task.task_defined?("release")
|
|
67
|
+
desc "Build inline_forms, tag, push to origin (GitHub) and push the gem to RubyGems"
|
|
68
|
+
task "release" => [ "build", "release:guard_clean",
|
|
69
|
+
"release:push_to_origin", "release:rubygem_push" ]
|
|
70
|
+
|
|
71
|
+
desc "Tag the release and push the commit + tag to origin (GitHub) only"
|
|
72
|
+
task "release:push_to_origin" do
|
|
73
|
+
version = InlineForms::VERSION
|
|
74
|
+
tag = "v#{version}"
|
|
75
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
|
76
|
+
unless system("git", "rev-parse", "-q", "--verify", "refs/tags/#{tag}",
|
|
77
|
+
out: File::NULL, err: File::NULL)
|
|
78
|
+
sh "git", "tag", tag
|
|
79
|
+
end
|
|
80
|
+
sh "git", "push", "origin", "refs/heads/#{branch}"
|
|
81
|
+
sh "git", "push", "origin", "refs/tags/#{tag}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
desc "Release inline_forms, inline_forms_installer and inline_forms_schema_edit to RubyGems (no app generation)"
|
|
45
85
|
task "release:all" => [
|
|
46
86
|
"build:all",
|
|
47
87
|
"release:guard_clean",
|
|
48
|
-
"release:
|
|
88
|
+
"release:push_to_origin",
|
|
49
89
|
"release:rubygem_push",
|
|
50
|
-
"installer:release:rubygem_push"
|
|
90
|
+
"installer:release:rubygem_push",
|
|
91
|
+
"schema_edit:release:rubygem_push"
|
|
51
92
|
]
|
|
52
93
|
|
|
53
94
|
require "rake/testtask"
|
|
@@ -137,6 +137,11 @@ class InlineFormsController < ApplicationController
|
|
|
137
137
|
@update_span = params[:update]
|
|
138
138
|
attributes = @inline_forms_attribute_list || @object.inline_forms_attribute_list
|
|
139
139
|
attributes.each do | attribute, form_element |
|
|
140
|
+
# Skip a row whose column is not migrated yet (model edited, migration
|
|
141
|
+
# not run). Writing it would raise; the new form shows it as a pending
|
|
142
|
+
# placeholder and does not submit a value for it.
|
|
143
|
+
next if InlineForms.attribute_pending_migration?(@object, attribute, form_element)
|
|
144
|
+
|
|
140
145
|
InlineForms.assert_plain_text_column!(object: @object, attribute: attribute, form_element: form_element)
|
|
141
146
|
send("#{form_element}_update", @object, attribute) unless form_element == :associated || (cancan_enabled? && cannot?(:read, @object, attribute))
|
|
142
147
|
end
|
|
@@ -186,6 +191,16 @@ class InlineFormsController < ApplicationController
|
|
|
186
191
|
@form_element = params[:form_element]
|
|
187
192
|
@sub_id = params[:sub_id]
|
|
188
193
|
@update_span = params[:update]
|
|
194
|
+
# Defense-in-depth: the UI renders a pending field as a read-only
|
|
195
|
+
# placeholder (never links to edit/update), but a hand-crafted request
|
|
196
|
+
# could still target a column that is not migrated yet. Refuse cleanly
|
|
197
|
+
# instead of 500ing on the missing column.
|
|
198
|
+
if InlineForms.attribute_pending_migration?(@object, @attribute, @form_element)
|
|
199
|
+
respond_to do |format|
|
|
200
|
+
format.html { render "inline_forms/field_pending", layout: "turbo_rails/frame", status: :unprocessable_entity }
|
|
201
|
+
end
|
|
202
|
+
return
|
|
203
|
+
end
|
|
189
204
|
InlineForms.assert_plain_text_column!(object: @object, attribute: @attribute, form_element: @form_element)
|
|
190
205
|
send("#{@form_element}_update", @object, @attribute)
|
|
191
206
|
# Branch on the actual save result. Previously the return value of
|
|
@@ -42,7 +42,10 @@
|
|
|
42
42
|
<% attributes.each do | attribute, form_element | -%>
|
|
43
43
|
<% unless form_element.to_sym == :associated || (cancan_enabled? && cannot?(:read, @object, attribute)) -%>
|
|
44
44
|
<% css_class_id = "attribute_#{attribute}_#{@object.id}" -%>
|
|
45
|
-
<% if
|
|
45
|
+
<% if InlineForms.attribute_pending_migration?(@object, attribute, form_element) %>
|
|
46
|
+
<%= render partial: "inline_forms/pending_migration_row",
|
|
47
|
+
locals: { object: @object, attribute: attribute } %>
|
|
48
|
+
<% elsif form_element && form_element.to_sym == :header %>
|
|
46
49
|
<div class="row form_element_header" >
|
|
47
50
|
<div class='large-12 column<%= " attribute_name attribute_#{attribute} form_element_#{form_element}" -%>' >
|
|
48
51
|
<%= @object.human_attribute_name(attribute) -%>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%# Rendered in place of a field whose column does not exist yet (the model
|
|
2
|
+
file has the attribute_list row but its migration has not run). Read-only,
|
|
3
|
+
harmless, self-explanatory — see InlineForms.attribute_pending_migration?. %>
|
|
4
|
+
<div class="row pending_migration_row <%= cycle('odd', 'even') %>">
|
|
5
|
+
<div class='medium-5 large-5 column'>
|
|
6
|
+
<%= render partial: "inline_forms/attribute_label",
|
|
7
|
+
locals: { object: object, attribute: attribute } -%>
|
|
8
|
+
</div>
|
|
9
|
+
<div class='medium-7 large-7 column'>
|
|
10
|
+
<span class="pending_migration_notice">
|
|
11
|
+
<%= t("inline_forms.pending_migration.notice",
|
|
12
|
+
default: "pending migration \u2014 run rails db:migrate") -%>
|
|
13
|
+
</span>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
@@ -23,7 +23,10 @@
|
|
|
23
23
|
<% attributes.each do | attribute, form_element | -%>
|
|
24
24
|
<% if cancan_disabled? || can?(:read, @object, attribute) %>
|
|
25
25
|
<% css_class_id = "#{@object.class.name.underscore}_#{@object.id}_#{attribute}" -%>
|
|
26
|
-
<% if
|
|
26
|
+
<% if InlineForms.attribute_pending_migration?(@object, attribute, form_element) %>
|
|
27
|
+
<%= render partial: "inline_forms/pending_migration_row",
|
|
28
|
+
locals: { object: @object, attribute: attribute } %>
|
|
29
|
+
<% elsif form_element == :header %>
|
|
27
30
|
<div class="row form_element_header">
|
|
28
31
|
<div class='large-12 column' >
|
|
29
32
|
<%= @object.class.human_attribute_name(attribute) -%>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<%# Turbo-frame response for a forced field request (show/edit/update) against
|
|
2
|
+
an attribute whose column does not exist yet. The UI never links here (the
|
|
3
|
+
row renders as a pending placeholder in _show), so this is defense-in-depth
|
|
4
|
+
for a hand-crafted request during the pre-migrate window. %>
|
|
5
|
+
<turbo-frame id="<%= @update_span %>">
|
|
6
|
+
<span class="pending_migration_notice">
|
|
7
|
+
<%= t("inline_forms.pending_migration.notice",
|
|
8
|
+
default: "pending migration \u2014 run rails db:migrate") -%>
|
|
9
|
+
</span>
|
|
10
|
+
</turbo-frame>
|
|
@@ -13,6 +13,37 @@ Description:
|
|
|
13
13
|
rejected. `_presentation`, `_list_order`, `_list_search`, and `_order` are
|
|
14
14
|
skipped unless you pass `--replace`.
|
|
15
15
|
|
|
16
|
+
Placement:
|
|
17
|
+
By default a new attribute_list row is inserted above the model's trailing
|
|
18
|
+
"metadata" block (its `:info` rows / created_at / updated_at, and a
|
|
19
|
+
`:header` directly above them) rather than at the very end, so an editable
|
|
20
|
+
field does not land inside the read-only info section. Override with:
|
|
21
|
+
|
|
22
|
+
--before=ATTR insert the new row before an existing attribute
|
|
23
|
+
--after=ATTR insert the new row after an existing attribute
|
|
24
|
+
|
|
25
|
+
If the named anchor is not found, the generator warns and falls back to the
|
|
26
|
+
default placement.
|
|
27
|
+
|
|
28
|
+
Value-bearing form elements:
|
|
29
|
+
Choice elements (dropdown_with_values, dropdown_with_integers,
|
|
30
|
+
dropdown_with_values_with_stars, radio_button, check_box,
|
|
31
|
+
scale_with_integers, scale_with_values) need a values hash as the 3rd row
|
|
32
|
+
element. The generator inserts a placeholder `{ 1 => 'one', 2 => 'two' }`
|
|
33
|
+
and warns; edit it to your real values.
|
|
34
|
+
|
|
35
|
+
Constraints and caveats:
|
|
36
|
+
- Additive only: the generated migration uses `add_column` / `add_reference`
|
|
37
|
+
(nullable, no default). Renaming, dropping, or making a column NOT NULL
|
|
38
|
+
(and the SQLite table-rebuild that would require) is out of scope; do
|
|
39
|
+
those by hand.
|
|
40
|
+
- Run `bundle exec rails db:migrate` after generating: the model row is
|
|
41
|
+
written immediately, but the column only exists once the migration runs.
|
|
42
|
+
- PaperTrail: versions recorded before this migration have no value for the
|
|
43
|
+
new column, so reverting an old record leaves the new column at its
|
|
44
|
+
default (nil), and the versions panel shows no history for it prior to
|
|
45
|
+
the migration.
|
|
46
|
+
|
|
16
47
|
Example:
|
|
17
48
|
rails generate inline_forms_addto User occupation:text_field birthdate:date organization:dropdown bio:rich_text
|
|
18
49
|
|