rs-activeadmin-searchable_select 4.0.5
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 +7 -0
- data/.actrc +20 -0
- data/.claude/commands/fix-tests.md +203 -0
- data/.github/workflows/ci.yml +170 -0
- data/.github/workflows/npm-publish.yml +47 -0
- data/.gitignore +27 -0
- data/.npmignore +58 -0
- data/.rspec +2 -0
- data/.rubocop.yml +67 -0
- data/.yardopts +2 -0
- data/AGENTS.md +39 -0
- data/Appraisals +15 -0
- data/CHANGELOG.md +24 -0
- data/CLAUDE.md +104 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +366 -0
- data/LICENSE.txt +25 -0
- data/README.md +439 -0
- data/Rakefile +4 -0
- data/bin/rspec +17 -0
- data/config/database.yml +16 -0
- data/config.ru +28 -0
- data/docs/activeadmin-4-detailed-reference.md +932 -0
- data/docs/activeadmin-4-gem-migration-guide.md +313 -0
- data/docs/combustion.md +213 -0
- data/docs/for-next-session.md +199 -0
- data/docs/guide-update-your-app.md +213 -0
- data/docs/propshaft-readme.md +121 -0
- data/docs/propshaft-upgrade.md +267 -0
- data/docs/rails-7-asset-pipeline.md +279 -0
- data/docs/setup-activeadmin-app.md +552 -0
- data/docs/setup-activeadmin-gem.md +535 -0
- data/docs/upload-system.md +225 -0
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile +11 -0
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile.lock +371 -0
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile +11 -0
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile.lock +366 -0
- data/lefthook.yml +17 -0
- data/lib/activeadmin/inputs/filters/searchable_select_input.rb +13 -0
- data/lib/activeadmin/inputs/searchable_select_input.rb +11 -0
- data/lib/activeadmin/searchable_select/engine.rb +17 -0
- data/lib/activeadmin/searchable_select/option_collection.rb +119 -0
- data/lib/activeadmin/searchable_select/resource_dsl_extension.rb +56 -0
- data/lib/activeadmin/searchable_select/resource_extension.rb +10 -0
- data/lib/activeadmin/searchable_select/select_input_extension.rb +159 -0
- data/lib/activeadmin/searchable_select/version.rb +5 -0
- data/lib/activeadmin/searchable_select.rb +20 -0
- data/lib/activeadmin-searchable_select.rb +4 -0
- data/lib/generators/active_admin/searchable_select/install/install_generator.rb +217 -0
- data/package-lock.json +18 -0
- data/package.json +45 -0
- data/rs-activeadmin-searchable_select.gemspec +38 -0
- data/sonar-project.properties +25 -0
- data/spec/features/ajax_params_spec.rb +31 -0
- data/spec/features/end_to_end_spec.rb +227 -0
- data/spec/features/filter_input_spec.rb +137 -0
- data/spec/features/form_input_spec.rb +122 -0
- data/spec/features/inline_ajax_setting_spec.rb +26 -0
- data/spec/features/input_errors_spec.rb +76 -0
- data/spec/features/input_html_options_spec.rb +30 -0
- data/spec/features/options_dsl_spec.rb +220 -0
- data/spec/features/production_build_spec.rb +108 -0
- data/spec/internal/app/admin/categories.rb +26 -0
- data/spec/internal/app/admin/dashboard.rb +29 -0
- data/spec/internal/app/admin/option_types.rb +19 -0
- data/spec/internal/app/admin/option_values.rb +30 -0
- data/spec/internal/app/admin/posts.rb +27 -0
- data/spec/internal/app/admin/products.rb +22 -0
- data/spec/internal/app/admin/rgb_colors.rb +25 -0
- data/spec/internal/app/admin/tag_names.rb +21 -0
- data/spec/internal/app/admin/test_ajax_params_category.rb +10 -0
- data/spec/internal/app/admin/test_ajax_params_post.rb +20 -0
- data/spec/internal/app/admin/test_form_post_class.rb +7 -0
- data/spec/internal/app/admin/test_form_post_custom.rb +11 -0
- data/spec/internal/app/admin/test_form_post_resource.rb +11 -0
- data/spec/internal/app/admin/test_form_post_resource_custom.rb +12 -0
- data/spec/internal/app/admin/test_inline_ajax_post.rb +9 -0
- data/spec/internal/app/admin/test_input_html_post.rb +11 -0
- data/spec/internal/app/admin/test_posts_display_text.rb +9 -0
- data/spec/internal/app/admin/test_posts_filter.rb +9 -0
- data/spec/internal/app/admin/test_posts_named.rb +9 -0
- data/spec/internal/app/admin/test_posts_pagination.rb +9 -0
- data/spec/internal/app/admin/test_posts_payload_lambda.rb +11 -0
- data/spec/internal/app/admin/test_posts_payload_proc.rb +9 -0
- data/spec/internal/app/admin/test_posts_scope_lambda.rb +8 -0
- data/spec/internal/app/admin/test_posts_scope_params.rb +8 -0
- data/spec/internal/app/admin/test_posts_scope_user.rb +8 -0
- data/spec/internal/app/admin/test_posts_text_attr.rb +5 -0
- data/spec/internal/app/admin/users.rb +23 -0
- data/spec/internal/app/admin/variants.rb +31 -0
- data/spec/internal/app/assets/config/manifest.js +1 -0
- data/spec/internal/app/assets/javascripts/active_admin.js +2 -0
- data/spec/internal/app/assets/javascripts/searchable_select_test.js +2 -0
- data/spec/internal/app/controllers/application_controller.rb +5 -0
- data/spec/internal/app/css/active_admin_source.css +81 -0
- data/spec/internal/app/js/active_admin.js +17 -0
- data/spec/internal/app/models/article.rb +12 -0
- data/spec/internal/app/models/category.rb +12 -0
- data/spec/internal/app/models/internal/tag_name.rb +14 -0
- data/spec/internal/app/models/internal_tag_name.rb +11 -0
- data/spec/internal/app/models/option_type.rb +12 -0
- data/spec/internal/app/models/option_value.rb +4 -0
- data/spec/internal/app/models/post.rb +15 -0
- data/spec/internal/app/models/product.rb +12 -0
- data/spec/internal/app/models/rgb_color.rb +16 -0
- data/spec/internal/app/models/user.rb +12 -0
- data/spec/internal/app/models/variant.rb +12 -0
- data/spec/internal/build_activeadmin_css.js +115 -0
- data/spec/internal/config/database.yml +7 -0
- data/spec/internal/config/environment.rb +48 -0
- data/spec/internal/config/initializers/active_admin.rb +53 -0
- data/spec/internal/config/initializers/assets.rb +9 -0
- data/spec/internal/config/initializers/searchable_select.rb +6 -0
- data/spec/internal/config/routes.rb +4 -0
- data/spec/internal/config.ru +4 -0
- data/spec/internal/db/schema.rb +63 -0
- data/spec/internal/db/seeds.rb +88 -0
- data/spec/internal/esbuild.config.js +30 -0
- data/spec/internal/inject-jquery.js +4 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/package/LICENSE.txt +25 -0
- data/spec/internal/package/README.md +439 -0
- data/spec/internal/package/package.json +45 -0
- data/spec/internal/package/src/index.js +1 -0
- data/spec/internal/package/src/searchable_select/init.js +1 -0
- data/spec/internal/package/src/searchable_select.css +1 -0
- data/spec/internal/package/src/searchable_select.scss +1 -0
- data/spec/internal/package-lock.json +1385 -0
- data/spec/internal/package.json +26 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/internal/spec/internal/app/css/active_admin_source.css +38 -0
- data/spec/internal/spec/internal/log/test.log +0 -0
- data/spec/internal/tailwind-active_admin.config.js +53 -0
- data/spec/rails_helper.rb +86 -0
- data/spec/spec_helper.rb +137 -0
- data/spec/support/active_admin_helpers.rb +17 -0
- data/spec/support/capybara.rb +8 -0
- data/spec/support/models.rb +88 -0
- data/spec/support/pluck_polyfill.rb +12 -0
- data/spec/support/reset_settings.rb +5 -0
- data/src/index.js +77 -0
- data/src/searchable_select/init.js +58 -0
- data/src/searchable_select.css +5 -0
- data/src/searchable_select.css.map +1 -0
- metadata +405 -0
@@ -0,0 +1,932 @@
|
|
1
|
+
# ActiveAdmin 4 Migration Guide for Gem Maintainers
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
This document provides a comprehensive guide for gem maintainers on how to update their gems to support ActiveAdmin 4, based on the changes made to the `activeadmin-searchable_select` gem. The migration involved addressing significant changes in asset handling, JavaScript module systems, dependency management, and CSS selectors.
|
6
|
+
|
7
|
+
## Key Migration Steps
|
8
|
+
|
9
|
+
### 1. Update Dependency Constraints
|
10
|
+
|
11
|
+
#### Ruby Version Requirements
|
12
|
+
- **Minimum Ruby version**: 3.2 (Ruby 3.0 and 3.1 are dropped in ActiveAdmin 4)
|
13
|
+
- Update your gemspec: `spec.required_ruby_version = '>= 3.2'`
|
14
|
+
|
15
|
+
#### Rails Version Requirements
|
16
|
+
- **Minimum Rails version**: 7.0 (Rails 6.1 support dropped)
|
17
|
+
- ActiveAdmin 4 supports Rails 7.x and 8.x
|
18
|
+
|
19
|
+
#### ActiveAdmin Version
|
20
|
+
```ruby
|
21
|
+
# In gemspec
|
22
|
+
spec.add_runtime_dependency 'activeadmin', ['>= 1.x', '< 5']
|
23
|
+
```
|
24
|
+
|
25
|
+
### 2. Asset Pipeline Migration
|
26
|
+
|
27
|
+
ActiveAdmin 4 moved away from the traditional Rails asset pipeline to modern JavaScript bundlers.
|
28
|
+
|
29
|
+
#### Key Changes:
|
30
|
+
- ActiveAdmin 4 assumes `cssbundling-rails` and `importmap-rails` are installed
|
31
|
+
- No longer uses `register_stylesheet` or `register_javascript` methods
|
32
|
+
- Requires explicit JavaScript module initialization
|
33
|
+
|
34
|
+
#### CSS bundling pattern (Rails 7 cssbundling + Tailwind)
|
35
|
+
|
36
|
+
- Build CSS to `app/assets/builds/active_admin.css` and expose it via `app/assets/config/manifest.js`:
|
37
|
+
- `//= link_tree ../builds`
|
38
|
+
- `//= link active_admin.css`
|
39
|
+
- `//= link active_admin.js`
|
40
|
+
- `//= link trumbowyg/icons.svg` (when using Trumbowyg)
|
41
|
+
- Keep a single Tailwind config at the Rails app root (avoid duplicates). Using ESM works well:
|
42
|
+
- `tailwind.config.mjs` with `import activeAdminPlugin from '@activeadmin/activeadmin/plugin'`
|
43
|
+
- Source file `app/assets/stylesheets/active_admin_source.css` contains Tailwind directives, gem overrides and imports.
|
44
|
+
- If Tailwind CLI does not inline vendor `@import` from `node_modules`, concatenate vendor CSS before building. Example build script:
|
45
|
+
|
46
|
+
```json
|
47
|
+
// spec/internal/package.json
|
48
|
+
{
|
49
|
+
"scripts": {
|
50
|
+
"build:css": "node ./build_css.js"
|
51
|
+
}
|
52
|
+
}
|
53
|
+
```
|
54
|
+
|
55
|
+
```js
|
56
|
+
// spec/internal/build_css.js
|
57
|
+
const fs = require('fs');
|
58
|
+
const path = require('path');
|
59
|
+
const { spawnSync } = require('child_process');
|
60
|
+
const root = __dirname;
|
61
|
+
const inputPath = path.join(root, 'app/assets/stylesheets/active_admin_source.css');
|
62
|
+
const vendorCssPath = path.join(root, 'node_modules/trumbowyg/dist/ui/trumbowyg.css');
|
63
|
+
const tmpPath = path.join(root, 'app/assets/stylesheets/__aa_tmp.css');
|
64
|
+
const outPath = path.join(root, 'app/assets/builds/active_admin.css');
|
65
|
+
const src = fs.readFileSync(inputPath, 'utf8').split(/\r?\n/);
|
66
|
+
const vendorCss = fs.readFileSync(vendorCssPath, 'utf8');
|
67
|
+
const tailwind = ['@tailwind base;','@tailwind components;','@tailwind utilities;'].join('\n');
|
68
|
+
const body = src.slice(3).filter(l => !l.includes('trumbowyg.css')).join('\n');
|
69
|
+
fs.writeFileSync(tmpPath, `${tailwind}\n\n${vendorCss}\n\n${body}`);
|
70
|
+
spawnSync('npx', ['tailwindcss','-c', path.join(root,'tailwind.config.mjs'),'-i', tmpPath,'-o', outPath], { stdio: 'inherit', cwd: root });
|
71
|
+
fs.unlinkSync(tmpPath);
|
72
|
+
```
|
73
|
+
|
74
|
+
This ensures vendor CSS (e.g., Trumbowyg) ships inside the built `active_admin.css` while keeping Tailwind at the top of the cascade so overrides behave as expected.
|
75
|
+
|
76
|
+
#### JavaScript Module Support
|
77
|
+
|
78
|
+
Create multiple module formats to support different bundlers:
|
79
|
+
|
80
|
+
1. **ESM Module** (`your_gem.esm.js`):
|
81
|
+
```javascript
|
82
|
+
import $ from 'jquery';
|
83
|
+
import select2 from 'select2'; // Or your jQuery plugin
|
84
|
+
|
85
|
+
// Critical: Initialize jQuery plugins on the jQuery object for production builds
|
86
|
+
// This ensures the plugin methods are available on jQuery selections
|
87
|
+
select2($);
|
88
|
+
|
89
|
+
// Ensure jQuery is globally available for other scripts
|
90
|
+
window.$ = window.jQuery = $;
|
91
|
+
|
92
|
+
// Your initialization code wrapped in a DOM ready handler
|
93
|
+
$(() => {
|
94
|
+
// Initialize your plugin on specific selectors
|
95
|
+
$('.your-selector').yourPlugin({
|
96
|
+
// plugin options
|
97
|
+
});
|
98
|
+
|
99
|
+
// Listen for Turbo/Turbolinks events for dynamic content
|
100
|
+
$(document).on('turbo:load turbolinks:load', () => {
|
101
|
+
$('.your-selector').yourPlugin();
|
102
|
+
});
|
103
|
+
|
104
|
+
// For ActiveAdmin's dynamic content (filters, forms)
|
105
|
+
$(document).on('has_many_add:after', '.has_many_container', () => {
|
106
|
+
$('.your-selector').yourPlugin();
|
107
|
+
});
|
108
|
+
});
|
109
|
+
|
110
|
+
// Export for use as a module
|
111
|
+
export default function initializeYourGem() {
|
112
|
+
// Initialization logic
|
113
|
+
}
|
114
|
+
```
|
115
|
+
|
116
|
+
2. **Traditional Module** (`your_gem.js` for backward compatibility):
|
117
|
+
```javascript
|
118
|
+
//= require jquery
|
119
|
+
//= require select2
|
120
|
+
|
121
|
+
(function($) {
|
122
|
+
'use strict';
|
123
|
+
|
124
|
+
$(document).ready(function() {
|
125
|
+
$('.your-selector').yourPlugin();
|
126
|
+
});
|
127
|
+
|
128
|
+
// Turbolinks/Turbo support
|
129
|
+
$(document).on('turbo:load turbolinks:load', function() {
|
130
|
+
$('.your-selector').yourPlugin();
|
131
|
+
});
|
132
|
+
})(jQuery);
|
133
|
+
```
|
134
|
+
|
135
|
+
3. **CDN-compatible version** (for importmap users):
|
136
|
+
```javascript
|
137
|
+
// Assumes jQuery and plugins are loaded via CDN
|
138
|
+
(() => {
|
139
|
+
'use strict';
|
140
|
+
|
141
|
+
const $ = window.jQuery || window.$;
|
142
|
+
|
143
|
+
if (!$) {
|
144
|
+
console.error('jQuery is required for YourGem');
|
145
|
+
return;
|
146
|
+
}
|
147
|
+
|
148
|
+
// Wait for DOM ready
|
149
|
+
$(() => {
|
150
|
+
$('.your-selector').yourPlugin();
|
151
|
+
});
|
152
|
+
})();
|
153
|
+
```
|
154
|
+
|
155
|
+
### 3. Installation Generator
|
156
|
+
|
157
|
+
Create a generator to help users set up your gem with different bundlers:
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
module YourGem
|
161
|
+
module Generators
|
162
|
+
class InstallGenerator < Rails::Generators::Base
|
163
|
+
class_option :bundler,
|
164
|
+
type: :string,
|
165
|
+
default: 'esbuild',
|
166
|
+
enum: %w[esbuild importmap webpack]
|
167
|
+
|
168
|
+
def setup_javascript
|
169
|
+
case options[:bundler]
|
170
|
+
when 'esbuild'
|
171
|
+
setup_esbuild
|
172
|
+
when 'importmap'
|
173
|
+
setup_importmap
|
174
|
+
when 'webpack'
|
175
|
+
setup_webpack
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def setup_esbuild
|
182
|
+
# Add imports to app/javascript/active_admin.js
|
183
|
+
append_to_file 'app/javascript/active_admin.js' do
|
184
|
+
<<~JS
|
185
|
+
import $ from 'jquery';
|
186
|
+
import yourPlugin from 'your-plugin';
|
187
|
+
|
188
|
+
// Initialize plugin on jQuery
|
189
|
+
yourPlugin($);
|
190
|
+
window.$ = window.jQuery = $;
|
191
|
+
|
192
|
+
import '@your-scope/your-gem';
|
193
|
+
JS
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def setup_importmap
|
198
|
+
# Add pins to config/importmap.rb
|
199
|
+
append_to_file 'config/importmap.rb' do
|
200
|
+
<<~RUBY
|
201
|
+
pin "jquery", to: "https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"
|
202
|
+
pin "your-plugin", to: "https://cdn.jsdelivr.net/npm/your-plugin/dist/plugin.min.js"
|
203
|
+
pin "your-gem", to: "your-gem.js"
|
204
|
+
RUBY
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
```
|
211
|
+
|
212
|
+
### 4. NPM Package Publishing
|
213
|
+
|
214
|
+
If your gem includes JavaScript, consider publishing an NPM package:
|
215
|
+
|
216
|
+
#### Package.json Configuration
|
217
|
+
```json
|
218
|
+
{
|
219
|
+
"name": "@activeadmin/your-gem",
|
220
|
+
"version": "1.0.0",
|
221
|
+
"description": "Your gem description for ActiveAdmin",
|
222
|
+
"main": "src/index.js",
|
223
|
+
"module": "src/index.js",
|
224
|
+
"exports": {
|
225
|
+
".": {
|
226
|
+
"import": "./src/index.js",
|
227
|
+
"require": "./src/index.js",
|
228
|
+
"default": "./src/index.js"
|
229
|
+
},
|
230
|
+
"./css": "./src/styles.scss"
|
231
|
+
},
|
232
|
+
"peerDependencies": {
|
233
|
+
"jquery": ">= 3.0, < 5",
|
234
|
+
"select2": "^4.0.13" // Add your dependencies here
|
235
|
+
},
|
236
|
+
"files": [
|
237
|
+
"src/**/*",
|
238
|
+
"app/assets/**/*",
|
239
|
+
"vendor/assets/**/*"
|
240
|
+
],
|
241
|
+
"scripts": {
|
242
|
+
"prepare_sources": "mkdir -p src && cp -r app/assets/javascripts/active_admin/* src/ && cp -r app/assets/stylesheets/active_admin/* src/",
|
243
|
+
"prepublishOnly": "npm run prepare_sources"
|
244
|
+
},
|
245
|
+
"repository": {
|
246
|
+
"type": "git",
|
247
|
+
"url": "https://github.com/your-org/your-gem.git"
|
248
|
+
},
|
249
|
+
"keywords": ["activeadmin", "rails", "your-feature"],
|
250
|
+
"author": "Your Name",
|
251
|
+
"license": "MIT"
|
252
|
+
}
|
253
|
+
```
|
254
|
+
|
255
|
+
#### Preparing JavaScript Assets for NPM
|
256
|
+
|
257
|
+
Create a script to copy your assets to the NPM package structure:
|
258
|
+
|
259
|
+
```bash
|
260
|
+
#!/bin/bash
|
261
|
+
# scripts/prepare_npm_package.sh
|
262
|
+
|
263
|
+
# Create src directory for NPM
|
264
|
+
mkdir -p src
|
265
|
+
|
266
|
+
# Copy JavaScript files
|
267
|
+
cp -r app/assets/javascripts/active_admin/* src/
|
268
|
+
|
269
|
+
# Copy SCSS files if needed
|
270
|
+
cp -r app/assets/stylesheets/active_admin/* src/
|
271
|
+
|
272
|
+
# Ensure ESM module is included
|
273
|
+
cp app/assets/javascripts/active_admin/your_gem.esm.js src/index.js
|
274
|
+
```
|
275
|
+
|
276
|
+
### 5. CSS Selector Updates
|
277
|
+
|
278
|
+
ActiveAdmin 4 introduced several CSS class changes:
|
279
|
+
|
280
|
+
| ActiveAdmin 3.x | ActiveAdmin 4.x |
|
281
|
+
|----------------|-----------------|
|
282
|
+
| `.filter_form` | `.filters-form` |
|
283
|
+
| `.tabs` component | Removed - use divs with Tailwind |
|
284
|
+
| `.columns` component | Replaced with Tailwind grid |
|
285
|
+
|
286
|
+
Update your JavaScript and CSS accordingly:
|
287
|
+
```javascript
|
288
|
+
// Old
|
289
|
+
$('.filter_form select').select2();
|
290
|
+
|
291
|
+
// New
|
292
|
+
$('.filters-form select').select2();
|
293
|
+
```
|
294
|
+
|
295
|
+
### 6. Testing Updates with Combustion
|
296
|
+
|
297
|
+
#### Complete Combustion Workflow for ActiveAdmin 4 Gems
|
298
|
+
|
299
|
+
**CRITICAL**: This workflow is specifically for testing ActiveAdmin extension gems with Combustion.
|
300
|
+
|
301
|
+
##### Step 1: Add Dependencies to Gemfile
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
# Gemfile (for development/testing)
|
305
|
+
gem 'combustion'
|
306
|
+
gem 'importmap-rails', '~> 2.0' # Required for ActiveAdmin 4
|
307
|
+
```
|
308
|
+
|
309
|
+
##### Step 2: Run Combustion Generator (MANDATORY!)
|
310
|
+
|
311
|
+
```bash
|
312
|
+
# NEVER manually create spec/internal structure!
|
313
|
+
bundle exec combust
|
314
|
+
```
|
315
|
+
|
316
|
+
This creates:
|
317
|
+
- `spec/internal/` - minimal Rails app structure
|
318
|
+
- `config.ru` - in gem root for `bundle exec rackup`
|
319
|
+
- Basic Rails directories and config files
|
320
|
+
|
321
|
+
##### Step 3: Set Up Test App Structure
|
322
|
+
|
323
|
+
After generator, create these files:
|
324
|
+
|
325
|
+
```bash
|
326
|
+
# Create necessary directories
|
327
|
+
mkdir -p spec/internal/app/models
|
328
|
+
mkdir -p spec/internal/app/admin
|
329
|
+
mkdir -p spec/internal/app/assets/stylesheets
|
330
|
+
mkdir -p spec/internal/app/javascript
|
331
|
+
mkdir -p spec/internal/config/initializers
|
332
|
+
```
|
333
|
+
|
334
|
+
##### Basic Combustion Configuration
|
335
|
+
```ruby
|
336
|
+
# spec/rails_helper.rb
|
337
|
+
ENV['RAILS_ENV'] ||= 'test'
|
338
|
+
|
339
|
+
require 'combustion'
|
340
|
+
|
341
|
+
# Initialize Combustion with only needed components
|
342
|
+
Combustion.path = 'spec/internal'
|
343
|
+
Combustion.initialize!(:active_record, :action_controller, :action_view) do
|
344
|
+
config.load_defaults Rails::VERSION::STRING.to_f if Rails::VERSION::MAJOR >= 7
|
345
|
+
end
|
346
|
+
|
347
|
+
require 'rspec/rails'
|
348
|
+
require 'capybara/rails'
|
349
|
+
```
|
350
|
+
|
351
|
+
##### Step 4: Configure config.ru (CRITICAL Loading Order!)
|
352
|
+
|
353
|
+
```ruby
|
354
|
+
# config.ru - MUST control loading order for ActiveAdmin!
|
355
|
+
require "rubygems"
|
356
|
+
require "bundler"
|
357
|
+
|
358
|
+
# DON'T use Bundler.require - it loads gems too early!
|
359
|
+
Bundler.setup(:default, :development)
|
360
|
+
|
361
|
+
# Load Rails and combustion first
|
362
|
+
require 'combustion'
|
363
|
+
|
364
|
+
# Initialize Combustion with Rails components
|
365
|
+
Combustion.initialize! :active_record, :action_controller, :action_view do
|
366
|
+
config.load_defaults Rails::VERSION::STRING.to_f if Rails::VERSION::MAJOR >= 7
|
367
|
+
end
|
368
|
+
|
369
|
+
# NOW we can load ActiveAdmin and its dependencies after Rails is initialized
|
370
|
+
require 'importmap-rails'
|
371
|
+
require 'active_admin'
|
372
|
+
require 'your_activeadmin_gem'
|
373
|
+
|
374
|
+
run Combustion::Application
|
375
|
+
```
|
376
|
+
|
377
|
+
##### Step 5: Configure ActiveAdmin Assets
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
# spec/internal/app/assets/stylesheets/active_admin.css
|
381
|
+
@tailwind base;
|
382
|
+
@tailwind components;
|
383
|
+
@tailwind utilities;
|
384
|
+
```
|
385
|
+
|
386
|
+
```ruby
|
387
|
+
# spec/internal/config/importmap.rb
|
388
|
+
pin "@activeadmin/activeadmin", to: "active_admin.js", preload: true
|
389
|
+
```
|
390
|
+
|
391
|
+
```javascript
|
392
|
+
// spec/internal/app/javascript/active_admin.js
|
393
|
+
// Placeholder for ActiveAdmin JS
|
394
|
+
console.log("ActiveAdmin loaded");
|
395
|
+
```
|
396
|
+
|
397
|
+
##### Step 6: Set Up Test Models and Admin Resources
|
398
|
+
|
399
|
+
```ruby
|
400
|
+
# spec/internal/db/schema.rb
|
401
|
+
ActiveRecord::Schema.define do
|
402
|
+
create_table :active_admin_comments, force: true do |t|
|
403
|
+
t.string :namespace
|
404
|
+
t.text :body
|
405
|
+
t.references :resource, polymorphic: true
|
406
|
+
t.references :author, polymorphic: true
|
407
|
+
t.timestamps
|
408
|
+
end
|
409
|
+
|
410
|
+
create_table :posts, force: true do |t|
|
411
|
+
t.string :title
|
412
|
+
t.text :body
|
413
|
+
t.text :description
|
414
|
+
t.timestamps
|
415
|
+
end
|
416
|
+
end
|
417
|
+
```
|
418
|
+
|
419
|
+
```ruby
|
420
|
+
# spec/internal/config/routes.rb
|
421
|
+
Rails.application.routes.draw do
|
422
|
+
ActiveAdmin.routes(self)
|
423
|
+
root to: 'admin/dashboard#index'
|
424
|
+
end
|
425
|
+
```
|
426
|
+
|
427
|
+
```ruby
|
428
|
+
# spec/internal/config/initializers/active_admin.rb
|
429
|
+
ActiveAdmin.setup do |config|
|
430
|
+
config.site_title = "Test App"
|
431
|
+
config.authentication_method = false
|
432
|
+
config.current_user_method = false
|
433
|
+
config.batch_actions = true
|
434
|
+
end
|
435
|
+
```
|
436
|
+
|
437
|
+
##### Step 7: Configure rails_helper.rb
|
438
|
+
|
439
|
+
```ruby
|
440
|
+
# spec/rails_helper.rb
|
441
|
+
ENV['RAILS_ENV'] ||= 'test'
|
442
|
+
|
443
|
+
require 'combustion'
|
444
|
+
|
445
|
+
Combustion.path = 'spec/internal'
|
446
|
+
Combustion.initialize!(:active_record, :action_controller, :action_view) do
|
447
|
+
config.load_defaults Rails::VERSION::STRING.to_f if Rails::VERSION::MAJOR >= 7
|
448
|
+
end
|
449
|
+
|
450
|
+
require 'rspec/rails'
|
451
|
+
require 'capybara/rails'
|
452
|
+
```
|
453
|
+
|
454
|
+
##### Step 8: Running the Test App
|
455
|
+
|
456
|
+
```bash
|
457
|
+
# Start the test app server
|
458
|
+
bundle exec rackup
|
459
|
+
# Visit http://localhost:9292/admin
|
460
|
+
```
|
461
|
+
|
462
|
+
#### Critical Testing Pitfall: Model Registration Conflicts
|
463
|
+
|
464
|
+
**Problem**: Dynamic ActiveAdmin registrations in tests conflict with static admin files.
|
465
|
+
|
466
|
+
**Solution**: Choose ONE approach per model:
|
467
|
+
|
468
|
+
1. **Static Registration** (for consistent configs):
|
469
|
+
```ruby
|
470
|
+
# spec/internal/app/admin/users.rb
|
471
|
+
ActiveAdmin.register User do
|
472
|
+
permit_params :name, :email
|
473
|
+
# Fixed configuration
|
474
|
+
end
|
475
|
+
```
|
476
|
+
|
477
|
+
2. **Dynamic Registration** (for varying configs):
|
478
|
+
```ruby
|
479
|
+
# spec/support/active_admin_helpers.rb
|
480
|
+
module ActiveAdminHelpers
|
481
|
+
module_function
|
482
|
+
|
483
|
+
def setup
|
484
|
+
ActiveAdmin.application = nil
|
485
|
+
yield # Dynamic registration block
|
486
|
+
reload_routes!
|
487
|
+
end
|
488
|
+
|
489
|
+
def reload_routes!
|
490
|
+
Rails.application.reload_routes!
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
# In test - NO static admin file for Post model
|
495
|
+
ActiveAdminHelpers.setup do
|
496
|
+
ActiveAdmin.register(Post) do
|
497
|
+
# Test-specific configuration
|
498
|
+
end
|
499
|
+
end
|
500
|
+
```
|
501
|
+
|
502
|
+
**Important**: Never mix static and dynamic registration for the same model!
|
503
|
+
|
504
|
+
#### Capybara Configuration with Playwright
|
505
|
+
```ruby
|
506
|
+
# spec/support/capybara.rb
|
507
|
+
require 'capybara-playwright-driver'
|
508
|
+
|
509
|
+
Capybara.register_driver :playwright do |app|
|
510
|
+
Capybara::Playwright::Driver.new(
|
511
|
+
app,
|
512
|
+
browser_type: :chromium,
|
513
|
+
headless: true,
|
514
|
+
viewport: { width: 1920, height: 1080 }
|
515
|
+
)
|
516
|
+
end
|
517
|
+
|
518
|
+
Capybara.default_driver = :rack_test
|
519
|
+
Capybara.javascript_driver = :playwright
|
520
|
+
|
521
|
+
# Important: Set server for JS tests
|
522
|
+
Capybara.server = :puma, { Silent: true }
|
523
|
+
```
|
524
|
+
|
525
|
+
#### Waiting for JavaScript/AJAX in Tests
|
526
|
+
```ruby
|
527
|
+
# spec/support/wait_helpers.rb
|
528
|
+
module WaitHelpers
|
529
|
+
def wait_for_ajax
|
530
|
+
Timeout.timeout(Capybara.default_max_wait_time) do
|
531
|
+
sleep 0.1
|
532
|
+
loop until finished_all_ajax_requests?
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
def finished_all_ajax_requests?
|
537
|
+
page.evaluate_script('jQuery.active').zero?
|
538
|
+
end
|
539
|
+
|
540
|
+
# For Select2 or similar plugins
|
541
|
+
def wait_for_select2
|
542
|
+
expect(page).to have_css('.select2-container', wait: 5)
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
RSpec.configure do |config|
|
547
|
+
config.include WaitHelpers, type: :feature
|
548
|
+
end
|
549
|
+
```
|
550
|
+
|
551
|
+
### 7. Production Build Issues
|
552
|
+
|
553
|
+
Common production issues and solutions:
|
554
|
+
|
555
|
+
#### Issue: JavaScript plugin not initialized
|
556
|
+
**Solution**: Explicitly initialize jQuery plugins
|
557
|
+
```javascript
|
558
|
+
import select2 from 'select2';
|
559
|
+
import $ from 'jquery';
|
560
|
+
|
561
|
+
// This is critical for production builds
|
562
|
+
select2($);
|
563
|
+
```
|
564
|
+
|
565
|
+
#### Issue: jQuery not globally available
|
566
|
+
**Solution**: Ensure global assignment
|
567
|
+
```javascript
|
568
|
+
window.$ = window.jQuery = $;
|
569
|
+
```
|
570
|
+
|
571
|
+
#### Issue: Assets not loading in production
|
572
|
+
**Solution**: Use CDN fallbacks or vendor assets
|
573
|
+
```ruby
|
574
|
+
# In your gem's engine.rb
|
575
|
+
class Engine < ::Rails::Engine
|
576
|
+
initializer 'your_gem.assets' do |app|
|
577
|
+
if Rails.env.production?
|
578
|
+
# Add fallback assets
|
579
|
+
end
|
580
|
+
end
|
581
|
+
end
|
582
|
+
```
|
583
|
+
|
584
|
+
### 8. CI/CD Updates
|
585
|
+
|
586
|
+
Update your GitHub Actions workflow:
|
587
|
+
|
588
|
+
```yaml
|
589
|
+
name: CI
|
590
|
+
on: [push, pull_request]
|
591
|
+
|
592
|
+
jobs:
|
593
|
+
test:
|
594
|
+
runs-on: ubuntu-latest
|
595
|
+
strategy:
|
596
|
+
matrix:
|
597
|
+
ruby: ['3.2', '3.3']
|
598
|
+
rails: ['7.0', '7.1', '7.2', '8.0']
|
599
|
+
activeadmin: ['4.0.0.beta16']
|
600
|
+
|
601
|
+
steps:
|
602
|
+
- uses: actions/checkout@v4
|
603
|
+
|
604
|
+
- name: Set up Ruby
|
605
|
+
uses: ruby/setup-ruby@v1
|
606
|
+
with:
|
607
|
+
ruby-version: ${{ matrix.ruby }}
|
608
|
+
bundler-cache: true
|
609
|
+
|
610
|
+
- name: Install Node.js
|
611
|
+
uses: actions/setup-node@v4
|
612
|
+
with:
|
613
|
+
node-version: '20'
|
614
|
+
|
615
|
+
- name: Install npm dependencies
|
616
|
+
run: npm install
|
617
|
+
|
618
|
+
- name: Install Playwright browsers
|
619
|
+
run: npx playwright install chromium
|
620
|
+
|
621
|
+
- name: Run tests
|
622
|
+
run: bundle exec rspec
|
623
|
+
```
|
624
|
+
|
625
|
+
### 9. Appraisals Configuration
|
626
|
+
|
627
|
+
Use Appraisal gem to test against multiple versions:
|
628
|
+
|
629
|
+
```ruby
|
630
|
+
# Appraisals file
|
631
|
+
appraise 'rails-7.x-active-admin-4.x' do
|
632
|
+
gem 'rails', '~> 7.0'
|
633
|
+
gem 'activeadmin', '~> 4.0.0.beta16'
|
634
|
+
gem 'propshaft' # Required - Sprockets not supported
|
635
|
+
end
|
636
|
+
|
637
|
+
appraise 'rails-8.x-active-admin-4.x' do
|
638
|
+
gem 'rails', '~> 8.0'
|
639
|
+
gem 'activeadmin', '~> 4.0.0.beta16'
|
640
|
+
# Rails 8 includes Propshaft by default
|
641
|
+
end
|
642
|
+
```
|
643
|
+
|
644
|
+
### 10. Common Pitfalls and Solutions
|
645
|
+
|
646
|
+
#### Pitfall 1: Select2 or similar jQuery plugins not working
|
647
|
+
**Root Cause**: Plugin not attached to jQuery object in production
|
648
|
+
**Solution**: Explicitly call `plugin($)` after importing
|
649
|
+
```javascript
|
650
|
+
import select2 from 'select2';
|
651
|
+
import $ from 'jquery';
|
652
|
+
select2($); // Critical - attaches plugin to jQuery
|
653
|
+
```
|
654
|
+
|
655
|
+
#### Pitfall 2: CSS classes not found
|
656
|
+
**Root Cause**: ActiveAdmin 4 changed many CSS selectors
|
657
|
+
**Solution**: Search and replace old selectors with new ones
|
658
|
+
- `.filter_form` → `.filters-form`
|
659
|
+
- `.select2-container` needs explicit initialization in tests
|
660
|
+
|
661
|
+
#### Pitfall 3: Tests passing locally but failing in CI
|
662
|
+
**Root Cause**: Missing JavaScript dependencies or browser drivers
|
663
|
+
**Solution**:
|
664
|
+
```yaml
|
665
|
+
# .github/workflows/ci.yml
|
666
|
+
- name: Install Playwright browsers
|
667
|
+
run: npx playwright install chromium
|
668
|
+
```
|
669
|
+
|
670
|
+
#### Pitfall 4: Assets not compiling in production
|
671
|
+
**Root Cause**: Missing bundler configuration
|
672
|
+
**Solution**: Provide clear setup instructions for each bundler type in your README
|
673
|
+
|
674
|
+
#### Pitfall 5: Model registration conflicts in tests
|
675
|
+
**Root Cause**: Static admin files override dynamic test registrations
|
676
|
+
**Solution**:
|
677
|
+
- Delete static admin files for models that need dynamic config
|
678
|
+
- Keep static files only for models with consistent config
|
679
|
+
- Never mix both approaches for the same model
|
680
|
+
|
681
|
+
#### Pitfall 6: Input HTML options not passing through
|
682
|
+
**Root Cause**: Options can be lost during form DSL processing
|
683
|
+
**Solution**: Test with clean models not affected by other registrations
|
684
|
+
```ruby
|
685
|
+
# Test with a model that has no static admin file
|
686
|
+
ActiveAdmin.register(TestModel) do
|
687
|
+
form do |f|
|
688
|
+
f.input :field, as: :searchable_select,
|
689
|
+
input_html: { class: 'custom-class' }
|
690
|
+
end
|
691
|
+
end
|
692
|
+
```
|
693
|
+
|
694
|
+
#### Pitfall 7: Flaky JavaScript tests
|
695
|
+
**Root Cause**: Not waiting for AJAX/DOM updates
|
696
|
+
**Solution**: Add proper wait helpers
|
697
|
+
```ruby
|
698
|
+
def wait_for_select2
|
699
|
+
expect(page).to have_css('.select2-container', wait: 5)
|
700
|
+
end
|
701
|
+
```
|
702
|
+
|
703
|
+
#### Pitfall 8: Rails 8 compatibility issues
|
704
|
+
**Root Cause**: Formtastic 5.0 changes, Ransack updates
|
705
|
+
**Solution**:
|
706
|
+
- Test against multiple Rails versions using Appraisal
|
707
|
+
- Ensure Ransack methods are defined in models
|
708
|
+
```ruby
|
709
|
+
def self.ransackable_attributes(_auth_object = nil)
|
710
|
+
%w[name title]
|
711
|
+
end
|
712
|
+
```
|
713
|
+
|
714
|
+
#### Pitfall 9: Combustion and ActiveAdmin Loading Order Issues
|
715
|
+
**Root Cause**: ActiveAdmin requires Rails components at load time, conflicts with Combustion's initialization
|
716
|
+
**Critical Issue**: ActiveAdmin's `Bundler.require` loads before Rails is initialized by Combustion
|
717
|
+
**Symptoms**:
|
718
|
+
- `uninitialized constant Formtastic::ActionView`
|
719
|
+
- `uninitialized constant ActiveSupport::Autoload`
|
720
|
+
- `uninitialized constant #<Class:ActiveAdmin>::Importmap`
|
721
|
+
- Rackup fails with various Rails component loading errors
|
722
|
+
**Solution**:
|
723
|
+
- Use `Bundler.setup` instead of `Bundler.require` in config.ru
|
724
|
+
- Load ActiveAdmin AFTER Combustion initializes Rails
|
725
|
+
- Include importmap-rails for ActiveAdmin 4
|
726
|
+
- Don't require ActiveAdmin components in gem's main file
|
727
|
+
```ruby
|
728
|
+
# Bad: In lib/your_gem.rb
|
729
|
+
require 'active_admin' # This loads too early!
|
730
|
+
require 'formtastic/inputs/your_input'
|
731
|
+
|
732
|
+
# Good: In engine.rb
|
733
|
+
initializer 'your_gem.setup', after: :load_config_initializers do
|
734
|
+
require 'active_admin' if defined?(Rails.application)
|
735
|
+
ActiveSupport.on_load(:active_admin) do
|
736
|
+
require 'formtastic/inputs/your_input'
|
737
|
+
end
|
738
|
+
end
|
739
|
+
```
|
740
|
+
|
741
|
+
#### Pitfall 10: ActiveAdmin 4 Asset Pipeline Requirements (CRITICAL FOR COMBUSTION GEMS)
|
742
|
+
**Root Cause**: ActiveAdmin 4 uses Tailwind CSS v3 with custom plugin, requires compilation
|
743
|
+
**Critical Issue**: CSS must be compiled through Tailwind with ActiveAdmin plugin
|
744
|
+
**Symptoms**:
|
745
|
+
- Unstyled admin pages (no proper layout, just basic HTML)
|
746
|
+
- CSS file exists but has 0 bytes or wrong content
|
747
|
+
- `The asset "active_admin.css" is not present in the asset pipeline`
|
748
|
+
|
749
|
+
**Complete Solution for Combustion-based Gems**:
|
750
|
+
|
751
|
+
1. **Add Dependencies** (Gemfile):
|
752
|
+
```ruby
|
753
|
+
gem 'importmap-rails', '~> 2.0'
|
754
|
+
gem 'tailwindcss-rails' # For bundled tailwindcss executable
|
755
|
+
```
|
756
|
+
|
757
|
+
2. **Install NPM packages** (in spec/internal):
|
758
|
+
```bash
|
759
|
+
cd spec/internal
|
760
|
+
npm init -y
|
761
|
+
npm install --save-dev tailwindcss@^3 # Use v3, not v4!
|
762
|
+
npm install --save-dev @activeadmin/activeadmin # For plugin (optional)
|
763
|
+
```
|
764
|
+
|
765
|
+
3. **Copy ActiveAdmin Plugin** (from Ruby gem):
|
766
|
+
```bash
|
767
|
+
cp $(bundle show activeadmin)/plugin.js spec/internal/activeadmin-plugin.js
|
768
|
+
```
|
769
|
+
|
770
|
+
4. **Create Tailwind Config** (spec/internal/tailwind.config.mjs):
|
771
|
+
```javascript
|
772
|
+
import activeAdminPlugin from './activeadmin-plugin.js';
|
773
|
+
import { execSync } from 'child_process';
|
774
|
+
|
775
|
+
const activeAdminPath = execSync('bundle show activeadmin', { encoding: 'utf-8' }).trim();
|
776
|
+
|
777
|
+
export default {
|
778
|
+
content: [
|
779
|
+
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
|
780
|
+
'./app/admin/**/*.{arb,erb,html,rb}',
|
781
|
+
'./app/views/**/*.{arb,erb,html}',
|
782
|
+
'./app/javascript/**/*.js'
|
783
|
+
],
|
784
|
+
darkMode: 'selector',
|
785
|
+
plugins: [activeAdminPlugin]
|
786
|
+
}
|
787
|
+
```
|
788
|
+
|
789
|
+
5. **Create Source CSS** (spec/internal/app/assets/stylesheets/active_admin_source.css):
|
790
|
+
```css
|
791
|
+
@tailwind base;
|
792
|
+
@tailwind components;
|
793
|
+
@tailwind utilities;
|
794
|
+
```
|
795
|
+
|
796
|
+
6. **Build CSS**:
|
797
|
+
```bash
|
798
|
+
cd spec/internal
|
799
|
+
npx tailwindcss -c tailwind.config.mjs \
|
800
|
+
-i app/assets/stylesheets/active_admin_source.css \
|
801
|
+
-o app/assets/stylesheets/active_admin_compiled.css \
|
802
|
+
--minify
|
803
|
+
```
|
804
|
+
|
805
|
+
7. **Configure Sprockets** (spec/internal/app/assets/stylesheets/active_admin.css):
|
806
|
+
```css
|
807
|
+
/*
|
808
|
+
* This imports the compiled Tailwind CSS with ActiveAdmin styles
|
809
|
+
*= require ./active_admin_compiled
|
810
|
+
*/
|
811
|
+
```
|
812
|
+
|
813
|
+
8. **Update Manifest** (spec/internal/app/assets/config/manifest.js):
|
814
|
+
```javascript
|
815
|
+
//= link_tree ../builds
|
816
|
+
//= link active_admin.css
|
817
|
+
```
|
818
|
+
|
819
|
+
9. **Create Build Task** (lib/tasks/active_admin.rake):
|
820
|
+
```ruby
|
821
|
+
namespace :active_admin do
|
822
|
+
desc 'Build Active Admin Tailwind stylesheets'
|
823
|
+
task :build do
|
824
|
+
require 'fileutils'
|
825
|
+
|
826
|
+
input = File.expand_path('../../spec/internal/app/assets/stylesheets/active_admin_source.css', __dir__)
|
827
|
+
output = File.expand_path('../../spec/internal/app/assets/stylesheets/active_admin_compiled.css', __dir__)
|
828
|
+
config = File.expand_path('../../spec/internal/tailwind.config.mjs', __dir__)
|
829
|
+
|
830
|
+
FileUtils.mkdir_p(File.dirname(output))
|
831
|
+
|
832
|
+
command = ['npx', 'tailwindcss', '-c', config, '-i', input, '-o', output, '--minify']
|
833
|
+
puts "Building Tailwind CSS: #{command.join(' ')}"
|
834
|
+
system(*command, exception: true)
|
835
|
+
puts "Tailwind CSS build complete: #{output}"
|
836
|
+
end
|
837
|
+
end
|
838
|
+
```
|
839
|
+
|
840
|
+
#### Pitfall 11: Formtastic Custom Inputs Not Loading in Combustion
|
841
|
+
**Root Cause**: Loading order issues with ActiveAdmin, Formtastic, and custom inputs
|
842
|
+
**Symptoms**:
|
843
|
+
- `Formtastic::UnknownInputError: Unable to find input class YourInput`
|
844
|
+
- Input works in production but not in Combustion test environment
|
845
|
+
|
846
|
+
**Solutions**:
|
847
|
+
|
848
|
+
1. **Immediate Fix in config.ru** (for Combustion):
|
849
|
+
```ruby
|
850
|
+
# config.ru
|
851
|
+
require 'combustion'
|
852
|
+
Combustion.initialize! :active_record, :action_controller, :action_view
|
853
|
+
|
854
|
+
require 'importmap-rails'
|
855
|
+
require 'active_admin'
|
856
|
+
require 'your_gem'
|
857
|
+
|
858
|
+
# Critical: Explicitly require custom inputs after everything else
|
859
|
+
require 'formtastic/inputs/your_input'
|
860
|
+
|
861
|
+
run Combustion::Application
|
862
|
+
```
|
863
|
+
|
864
|
+
2. **Engine Initialization Fix**:
|
865
|
+
```ruby
|
866
|
+
# lib/your_gem/engine.rb
|
867
|
+
initializer 'your_gem.setup', after: :load_config_initializers do
|
868
|
+
require 'active_admin' if defined?(Rails.application)
|
869
|
+
|
870
|
+
# Load immediately AND hook into ActiveAdmin
|
871
|
+
require 'formtastic/inputs/your_input'
|
872
|
+
|
873
|
+
ActiveSupport.on_load(:active_admin) do
|
874
|
+
require 'formtastic/inputs/your_input'
|
875
|
+
end
|
876
|
+
end
|
877
|
+
```
|
878
|
+
|
879
|
+
3. **Workaround Using Standard Inputs**:
|
880
|
+
```ruby
|
881
|
+
# If custom input isn't loading, use standard input with same attributes
|
882
|
+
f.input :field, as: :text, input_html: {
|
883
|
+
class: 'your-input-class',
|
884
|
+
'data-your-attribute': true
|
885
|
+
}
|
886
|
+
```
|
887
|
+
|
888
|
+
**Note**: After making these changes, restart the server for them to take effect.
|
889
|
+
|
890
|
+
## Migration Checklist
|
891
|
+
|
892
|
+
- [ ] Update Ruby version requirement to >= 3.2
|
893
|
+
- [ ] Update Rails version requirement to >= 7.0
|
894
|
+
- [ ] Update ActiveAdmin dependency to support 4.x
|
895
|
+
- [ ] Create ESM JavaScript modules
|
896
|
+
- [ ] Add installation generator for different bundlers
|
897
|
+
- [ ] Publish NPM package (if applicable)
|
898
|
+
- [ ] Update CSS selectors (`.filter_form` → `.filters-form`)
|
899
|
+
- [ ] Fix jQuery plugin initialization for production
|
900
|
+
- [ ] Update test suite for new asset handling
|
901
|
+
- [ ] Configure CI for multiple version testing
|
902
|
+
- [ ] Update documentation with setup instructions
|
903
|
+
- [ ] Test with esbuild, webpack, and importmap
|
904
|
+
- [ ] Add CDN fallbacks for JavaScript dependencies
|
905
|
+
- [ ] Handle both Sprockets and Propshaft
|
906
|
+
|
907
|
+
## Example Implementation
|
908
|
+
|
909
|
+
See the full implementation in the `activeadmin-searchable_select` gem:
|
910
|
+
- [Installation Generator](../lib/generators/active_admin/searchable_select/install/install_generator.rb)
|
911
|
+
- [ESM Module](../app/assets/javascripts/active_admin/searchable_select.esm.js)
|
912
|
+
- [Package.json](../package.json)
|
913
|
+
- [CI Configuration](../.github/workflows/ci.yml)
|
914
|
+
|
915
|
+
## Resources
|
916
|
+
|
917
|
+
- [ActiveAdmin 4.0 Breaking Changes](./activeadmin-4-changes.md)
|
918
|
+
- [ActiveAdmin 4.0 Release Notes](https://github.com/activeadmin/activeadmin/releases)
|
919
|
+
- [Rails 7+ Asset Pipeline Guide](https://guides.rubyonrails.org/asset_pipeline.html)
|
920
|
+
- [esbuild Rails Documentation](https://github.com/rails/jsbundling-rails)
|
921
|
+
- [Importmap Rails Documentation](https://github.com/rails/importmap-rails)
|
922
|
+
|
923
|
+
## Conclusion
|
924
|
+
|
925
|
+
Migrating a gem to support ActiveAdmin 4 requires careful attention to:
|
926
|
+
1. Modern JavaScript module systems
|
927
|
+
2. Flexible asset pipeline support
|
928
|
+
3. Updated CSS selectors and components
|
929
|
+
4. Proper jQuery plugin initialization
|
930
|
+
5. Comprehensive testing across different setups
|
931
|
+
|
932
|
+
The key to success is providing multiple paths for users with different asset pipeline configurations while maintaining backward compatibility where possible.
|