activeadmin-tom_select 4.1.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 +7 -0
- data/.actrc +20 -0
- data/.claude/commands/fix-tests.md +203 -0
- data/.github/workflows/ci.yml +174 -0
- data/.github/workflows/npm-publish.yml +50 -0
- data/.gitignore +35 -0
- data/.npmignore +58 -0
- data/.rspec +1 -0
- data/.rubocop.yml +75 -0
- data/.yardopts +2 -0
- data/AGENTS.md +39 -0
- data/Appraisals +9 -0
- data/CHANGELOG.md +64 -0
- data/CLAUDE.md +157 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +368 -0
- data/LICENSE.txt +25 -0
- data/README.md +483 -0
- data/Rakefile +4 -0
- data/activeadmin-tom_select.gemspec +43 -0
- data/bin/rspec +17 -0
- data/config/database.yml +16 -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/fail.png +0 -0
- data/docs/guide-update-your-app.md +283 -0
- data/docs/normal.png +0 -0
- data/docs/propshaft-readme.md +320 -0
- data/docs/propshaft-upgrade.md +484 -0
- data/docs/setup-activeadmin-app.md +552 -0
- data/docs/setup-activeadmin-gem.md +535 -0
- data/docs/tailwind/blog-page.md +341 -0
- data/docs/tailwind/upgrade-guide-enhanced.md +438 -0
- data/docs/tailwind/upgrade-guide.md +416 -0
- data/docs/tailwind-4/active_admin.rake +38 -0
- data/docs/tailwind-4/active_admin.tailwind.css +415 -0
- data/docs/tailwind-4/tailwind-active_admin.config.js +18 -0
- data/docs/test-app-change.md +154 -0
- data/docs/test-environment-fixes.md +58 -0
- data/docs/update-tom-select.md +184 -0
- data/docs/upload-system.md +225 -0
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile +10 -0
- data/gemfiles/rails_7.x_active_admin_4.x.gemfile.lock +377 -0
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile +10 -0
- data/gemfiles/rails_8.x_active_admin_4.x.gemfile.lock +372 -0
- data/lefthook.yml +17 -0
- data/lib/activeadmin/inputs/filters/searchable_select_input.rb +19 -0
- data/lib/activeadmin/inputs/searchable_select_input.rb +16 -0
- data/lib/activeadmin/tom_select/engine.rb +17 -0
- data/lib/activeadmin/tom_select/option_collection.rb +128 -0
- data/lib/activeadmin/tom_select/resource_dsl_extension.rb +56 -0
- data/lib/activeadmin/tom_select/resource_extension.rb +10 -0
- data/lib/activeadmin/tom_select/select_input_extension.rb +168 -0
- data/lib/activeadmin/tom_select/version.rb +5 -0
- data/lib/activeadmin/tom_select.rb +20 -0
- data/lib/activeadmin-tom_select.rb +5 -0
- data/lib/generators/active_admin/tom_select/install/install_generator.rb +180 -0
- data/npm-package/package-lock.json +51 -0
- data/npm-package/package.json +43 -0
- data/npm-package/src/index.js +153 -0
- data/npm-package/src/tom-select-tailwind.css +392 -0
- data/sonar-project.properties +25 -0
- data/spec/features/ajax_params_spec.rb +31 -0
- data/spec/features/asset_pipeline_diagnostic_spec.rb +155 -0
- data/spec/features/end_to_end_spec.rb +273 -0
- data/spec/features/filter_input_spec.rb +144 -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 +230 -0
- data/spec/features/production_build_spec.rb +108 -0
- data/spec/internal/.node-version +1 -0
- data/spec/internal/Gemfile +43 -0
- data/spec/internal/Gemfile.lock +333 -0
- data/spec/internal/Procfile.dev +3 -0
- data/spec/internal/README.md +24 -0
- data/spec/internal/Rakefile +6 -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 +2 -0
- data/spec/internal/app/assets/images/.keep +0 -0
- data/spec/internal/app/assets/stylesheets/active_admin.tailwind.css +16 -0
- data/spec/internal/app/assets/stylesheets/application.tailwind.css +15 -0
- data/spec/internal/app/controllers/application_controller.rb +9 -0
- data/spec/internal/app/controllers/concerns/.keep +0 -0
- data/spec/internal/app/helpers/application_helper.rb +2 -0
- data/spec/internal/app/javascript/active_admin.js +19 -0
- data/spec/internal/app/javascript/application.js +2 -0
- data/spec/internal/app/jobs/application_job.rb +7 -0
- data/spec/internal/app/mailers/application_mailer.rb +4 -0
- data/spec/internal/app/models/admin_user.rb +9 -0
- data/spec/internal/app/models/application_record.rb +3 -0
- data/spec/internal/app/models/article.rb +12 -0
- data/spec/internal/app/models/category.rb +12 -0
- data/spec/internal/app/models/color.rb +9 -0
- data/spec/internal/app/models/concerns/.keep +0 -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/tag.rb +12 -0
- data/spec/internal/app/models/tagging.rb +12 -0
- data/spec/internal/app/models/user.rb +12 -0
- data/spec/internal/app/models/variant.rb +12 -0
- data/spec/internal/app/views/layouts/application.html.erb +28 -0
- data/spec/internal/app/views/layouts/mailer.html.erb +13 -0
- data/spec/internal/app/views/layouts/mailer.text.erb +1 -0
- data/spec/internal/app/views/pwa/manifest.json.erb +22 -0
- data/spec/internal/app/views/pwa/service-worker.js +26 -0
- data/spec/internal/bin/bundle +117 -0
- data/spec/internal/bin/dev +11 -0
- data/spec/internal/bin/rackup +27 -0
- data/spec/internal/bin/rails +4 -0
- data/spec/internal/bin/rake +4 -0
- data/spec/internal/bin/setup +37 -0
- data/spec/internal/config/application.rb +50 -0
- data/spec/internal/config/boot.rb +3 -0
- data/spec/internal/config/credentials.yml.enc +1 -0
- data/spec/internal/config/database.yml +32 -0
- data/spec/internal/config/environment.rb +5 -0
- data/spec/internal/config/environments/development.rb +63 -0
- data/spec/internal/config/environments/production.rb +86 -0
- data/spec/internal/config/environments/test.rb +50 -0
- data/spec/internal/config/initializers/active_admin.rb +54 -0
- data/spec/internal/config/initializers/assets.rb +8 -0
- data/spec/internal/config/initializers/content_security_policy.rb +25 -0
- data/spec/internal/config/initializers/devise.rb +315 -0
- data/spec/internal/config/initializers/filter_parameter_logging.rb +8 -0
- data/spec/internal/config/initializers/inflections.rb +16 -0
- data/spec/internal/config/initializers/searchable_select.rb +6 -0
- data/spec/internal/config/locales/devise.en.yml +65 -0
- data/spec/internal/config/locales/en.yml +31 -0
- data/spec/internal/config/master.key +1 -0
- data/spec/internal/config/puma.rb +38 -0
- data/spec/internal/config/routes.rb +17 -0
- data/spec/internal/config.ru +6 -0
- data/spec/internal/db/schema.rb +174 -0
- data/spec/internal/db/seeds.rb +167 -0
- data/spec/internal/esbuild.config.js +34 -0
- data/spec/internal/lib/tasks/.keep +0 -0
- data/spec/internal/lib/tasks/active_admin.rake +55 -0
- data/spec/internal/log/.keep +0 -0
- data/spec/internal/package-lock.json +1954 -0
- data/spec/internal/package.json +21 -0
- data/spec/internal/public/400.html +114 -0
- data/spec/internal/public/404.html +114 -0
- data/spec/internal/public/406-unsupported-browser.html +114 -0
- data/spec/internal/public/422.html +114 -0
- data/spec/internal/public/500.html +114 -0
- data/spec/internal/public/icon.png +0 -0
- data/spec/internal/public/icon.svg +3 -0
- data/spec/internal/public/robots.txt +1 -0
- data/spec/internal/script/.keep +0 -0
- data/spec/internal/storage/.keep +0 -0
- data/spec/internal/tailwind.config.js +23 -0
- data/spec/internal/vendor/.keep +0 -0
- data/spec/internal/yarn.lock +824 -0
- data/spec/rails_helper.rb +62 -0
- data/spec/spec_helper.rb +138 -0
- data/spec/support/active_admin_helpers.rb +17 -0
- data/spec/support/capybara.rb +8 -0
- data/spec/support/models.rb +11 -0
- data/spec/support/pluck_polyfill.rb +12 -0
- data/spec/support/reset_settings.rb +5 -0
- metadata +497 -0
@@ -0,0 +1,484 @@
|
|
1
|
+
# Upgrading from Sprockets to Propshaft
|
2
|
+
|
3
|
+
Propshaft has a smaller scope than Sprockets, therefore migrating to it will also require you to adopt the [jsbundling-rails](https://github.com/rails/jsbundling-rails) and [cssbundling-rails](https://github.com/rails/cssbundling-rails) gems. This guide will assume your project follows Rails 6.1 conventions of using [webpacker](https://github.com/rails/webpacker) to bundle javascript, [sass-rails](https://github.com/rails/sass-rails) to bundle css and [sprockets](https://github.com/rails/sprockets) to digest assets. Finally, you will also need [npx](https://docs.npmjs.com/cli/v7/commands/npx) version 7.1.0 or later installed.
|
4
|
+
|
5
|
+
Propshaft depends on Rails 7, so you will need to upgrade to Rails 7+ before starting the migration.
|
6
|
+
|
7
|
+
## 1. Migrate from Webpacker to jsbundling-rails
|
8
|
+
|
9
|
+
Start by following these steps:
|
10
|
+
|
11
|
+
1. Replace `webpacker` with `jsbundling-rails` in your Gemfile;
|
12
|
+
2. Run `./bin/bundle install`;
|
13
|
+
3. Run `./bin/rails javascript:install:webpack`;
|
14
|
+
4. Remove the file `config/initializers/assets.rb`;
|
15
|
+
5. Remove the file `bin/webpack`;
|
16
|
+
6. Remove the file `bin/webpack-dev-server`;
|
17
|
+
7. Remove the folder `config/webpack` (note: any custom configuration should be migrated to the new `webpack.config.js` file);
|
18
|
+
8. Remove the file `config/webpacker.yml`;
|
19
|
+
9. Replace all instances of `javascript_pack_tag` with `javascript_include_tag` and add `defer: true` to them.
|
20
|
+
|
21
|
+
After you are done you will notice that the install step added various files to your project and updated some of the existing ones.
|
22
|
+
|
23
|
+
**The new 'bin/dev' and 'Procfile.dev' files**
|
24
|
+
|
25
|
+
The `./bin/dev` file is a shell script that uses [foreman](https://github.com/ddollar/foreman) and `Procfile.dev` to start two processes in a single terminal: `rails s` and `yarn build`. The latter replaces `webpack-dev-server` for bundling and watching for changes in javascript files.
|
26
|
+
|
27
|
+
**The 'build' attribute added to package.json**
|
28
|
+
|
29
|
+
This is the command that `yarn build` will use to bundle javascript files.
|
30
|
+
|
31
|
+
**The new 'webpack.config.js' file**
|
32
|
+
|
33
|
+
In `webpacker` this file was hidden inside the gem, but now you can edit it directly. If you had custom configuration in `config/webpack` you can move them to here. Projects with multiple entrypoints will need to adjust the `entry` attribute:
|
34
|
+
|
35
|
+
```js
|
36
|
+
module.exports = {
|
37
|
+
entry: {
|
38
|
+
application: "./app/javascript/application.js",
|
39
|
+
admin: "./app/javascript/admin.js"
|
40
|
+
}
|
41
|
+
}
|
42
|
+
```
|
43
|
+
|
44
|
+
**The 'link_tree' directive added to 'app/assets/manifest.js'**
|
45
|
+
|
46
|
+
This tells Sprockets to include the files in `app/assets/builds` during `assets:precompile`. This is the folder where `yarn build` will place the bundled files, so make sure you commit it to the repository and don't delete it when cleaning assets.
|
47
|
+
|
48
|
+
**What about babel?**
|
49
|
+
|
50
|
+
If you would like to continue using babel for transpiling, you will need to configure it manually. First, open `webpack.config.js` and add this:
|
51
|
+
|
52
|
+
```js
|
53
|
+
module.exports = {
|
54
|
+
module: {
|
55
|
+
rules: [
|
56
|
+
{
|
57
|
+
test: /\.(js)$/,
|
58
|
+
exclude: /node_modules/,
|
59
|
+
use: ['babel-loader']
|
60
|
+
}
|
61
|
+
]
|
62
|
+
}
|
63
|
+
}
|
64
|
+
```
|
65
|
+
|
66
|
+
Then open `package.json` and add this:
|
67
|
+
```json
|
68
|
+
"babel": {
|
69
|
+
"presets": [
|
70
|
+
"./webpack.babel.js"
|
71
|
+
]
|
72
|
+
}
|
73
|
+
```
|
74
|
+
|
75
|
+
Finally, download [webpackers babel preset](https://github.com/rails/webpacker/blob/master/package/babel/preset.js) file and place it in the same directory as `package.json` with the name `webpack.babel.js`.
|
76
|
+
|
77
|
+
**Module resolution**
|
78
|
+
|
79
|
+
Webpacker included the `source_path` (default: `app/javascript/`) into module resolution, so a statement like `import 'channels'` imported `app/javascript/channels/`. After migrating to `jsbundling-rails` this is no longer the case. You will need to update your `webpack.config.js` to include the following if you wish to maintain that behavior:
|
80
|
+
|
81
|
+
```javascript
|
82
|
+
module.exports = {
|
83
|
+
// ...
|
84
|
+
resolve: {
|
85
|
+
modules: ["app/javascript", "node_modules"],
|
86
|
+
},
|
87
|
+
//...
|
88
|
+
}
|
89
|
+
```
|
90
|
+
|
91
|
+
Alternatively, you can change modules to use relative imports, for example:
|
92
|
+
```diff
|
93
|
+
- import 'channels'
|
94
|
+
+ import './channels'
|
95
|
+
```
|
96
|
+
|
97
|
+
### Extracting Sass/SCSS from JavaScript
|
98
|
+
|
99
|
+
In webpacker it is possible to extract Sass/SCSS from JavaScript by enabling `extract_css` in `webpacker.yml`. This allows for including those source files in JavaScript, e.g. `import '../scss/application.scss`
|
100
|
+
|
101
|
+
If you wish to keep this functionality follow these steps:
|
102
|
+
|
103
|
+
1. Run `yarn add mini-css-extract-plugin sass sass-loader css-loader`;
|
104
|
+
2. Update your `webpack.config.js` to require `mini-css-extract-plugin` and configure the loaders (see example below).
|
105
|
+
|
106
|
+
Example `webpack.config.js`:
|
107
|
+
|
108
|
+
```javascript
|
109
|
+
const path = require("path")
|
110
|
+
const webpack = require("webpack")
|
111
|
+
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
|
112
|
+
|
113
|
+
module.exports = {
|
114
|
+
mode: "production",
|
115
|
+
devtool: "source-map",
|
116
|
+
entry: {
|
117
|
+
application: "./app/javascript/application.js"
|
118
|
+
},
|
119
|
+
resolve: {
|
120
|
+
modules: ["app/javascript", "node_modules"],
|
121
|
+
},
|
122
|
+
output: {
|
123
|
+
filename: "[name].js",
|
124
|
+
sourceMapFilename: "[file].map",
|
125
|
+
path: path.resolve(__dirname, "app/assets/builds"),
|
126
|
+
},
|
127
|
+
plugins: [
|
128
|
+
new MiniCssExtractPlugin(),
|
129
|
+
new webpack.optimize.LimitChunkCountPlugin({
|
130
|
+
maxChunks: 1
|
131
|
+
})
|
132
|
+
],
|
133
|
+
module: {
|
134
|
+
rules: [
|
135
|
+
{
|
136
|
+
test: /\.s[ac]ss$/i,
|
137
|
+
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
|
138
|
+
},
|
139
|
+
],
|
140
|
+
},
|
141
|
+
}
|
142
|
+
```
|
143
|
+
|
144
|
+
## 2. Migrate from sass-rails to cssbundling-rails
|
145
|
+
|
146
|
+
Note: if your application used Webpacker's `extract_css` to build your CSS and did not require `sass-rails`, you can skip this section.
|
147
|
+
|
148
|
+
Start by following these steps:
|
149
|
+
|
150
|
+
1. Add `cssbundling-rails` to your Gemfile;
|
151
|
+
2. Run `./bin/bundle install`;
|
152
|
+
3. Run `./bin/rails css:install:sass`.
|
153
|
+
|
154
|
+
After you are done you will notice that the install step updated some files.
|
155
|
+
|
156
|
+
**The new process in 'Procfile.dev'**
|
157
|
+
|
158
|
+
Just like the javascript process, this one will bundle and watch for changes in css files.
|
159
|
+
|
160
|
+
**The 'build:css' attribute added to package.json**
|
161
|
+
|
162
|
+
This is the command `yarn build` will use to bundle css files.
|
163
|
+
|
164
|
+
**The 'link_tree' directive removed from 'app/assets/manifest.js'**
|
165
|
+
|
166
|
+
Now that the CSS files will be placed into `app/assets/build`, Sprockets no longer needs to worry about the `app/assets/stylesheets` folder. If you have any other `link_tree` for css files, remove them too.
|
167
|
+
|
168
|
+
### Configuring multiple entrypoints
|
169
|
+
|
170
|
+
Sprockets will only compile files in the root directories listed in `manifest.js`, but the sass package that `yarn build` uses will also check subfolders, which might cause compilation errors if your scss files are using features like `@import` and variables. This means that if you have multiple entry points in your app, you have some extra work ahead of you.
|
171
|
+
|
172
|
+
Let's assume you have the following structure in your `app/asset/stylesheets` folder:
|
173
|
+
|
174
|
+
```
|
175
|
+
stylesheets/admin.scss
|
176
|
+
stylesheets/admin/source_1.scss
|
177
|
+
stylesheets/admin/source_2.scss
|
178
|
+
stylesheets/application.scss
|
179
|
+
stylesheets/application/source_1.scss
|
180
|
+
stylesheets/application/source_2.scss
|
181
|
+
```
|
182
|
+
|
183
|
+
Start by your separating your entrypoints from your other files, and adjusting all `@import` for the new structure:
|
184
|
+
|
185
|
+
```
|
186
|
+
stylesheets/entrypoints/admin.scss
|
187
|
+
stylesheets/entrypoints/application.scss
|
188
|
+
stylesheets/sources/admin/source_1.scss
|
189
|
+
stylesheets/sources/admin/source_2.scss
|
190
|
+
stylesheets/sources/application/source_1.scss
|
191
|
+
stylesheets/sources/application/source_2.scss
|
192
|
+
```
|
193
|
+
|
194
|
+
Then adjust the `build` attribute in `package.json`:
|
195
|
+
```
|
196
|
+
"build:css": "sass ./app/assets/stylesheets/entrypoints:./app/assets/builds --no-source-map --load-path=node_modules"
|
197
|
+
```
|
198
|
+
|
199
|
+
### Deprecation warnings
|
200
|
+
|
201
|
+
Sass might raise deprecation warnings depending on what features you are using (such as division), but the messages will explain how to fix them. If you are not sure, see more details in the [official documentation](https://sass-lang.com/documentation/breaking-changes).
|
202
|
+
|
203
|
+
## 3. Migrate from Sprockets to Propshaft
|
204
|
+
|
205
|
+
Start by following these steps:
|
206
|
+
|
207
|
+
1. Remove `sprockets`, `sprockets-rails`, and `sass-rails` from the Gemfile and add `propshaft`;
|
208
|
+
2. Run `./bin/bundle install`;
|
209
|
+
3. Check your `Gemfile.lock`, repeat steps 1 and 2 for gems that list `sprockets` or `sprockets-rails` as a dependency;
|
210
|
+
4. Open `config/application.rb` and remove `config.assets.paths << Rails.root.join('app','assets')`;
|
211
|
+
5. Remove `app/assets/config/manifest.js`.
|
212
|
+
6. Replace all asset_helpers (`image_url`, `font_url`) in css files with standard `urls`.
|
213
|
+
7. If you are importing only the frameworks you need (instead of `rails/all`), remove `require "sprockets/railtie"`;
|
214
|
+
|
215
|
+
### Asset paths
|
216
|
+
|
217
|
+
Propshaft will automatically include in its search paths the folders `vendor/assets`, `lib/assets` and `app/assets` of your project and of all the gems in your Gemfile. You can see all included files by using the `reveal` rake task:
|
218
|
+
```
|
219
|
+
rake assets:reveal
|
220
|
+
```
|
221
|
+
|
222
|
+
### Asset helpers
|
223
|
+
|
224
|
+
Propshaft does not rely on asset_helpers (`asset_path`, `asset_url`, `image_url`, etc.) like Sprockets did. Instead, it will search for every `url` function in your css files, and adjust them to include the digest of the assets they reference.
|
225
|
+
|
226
|
+
Go through your css files, and make the necessary adjustments:
|
227
|
+
```diff
|
228
|
+
- background: image_url('hero.jpg');
|
229
|
+
+ background: url('/hero.jpg');
|
230
|
+
```
|
231
|
+
|
232
|
+
Notice that Propshaft's version starts with an `/` and Sprockets' version does not? That's because the latter uses **absolute paths**, and the former uses **relative paths**. To better illustrate that difference, let's assume you have the following structure:
|
233
|
+
|
234
|
+
```
|
235
|
+
assets/stylesheets/theme/main.scss
|
236
|
+
assets/images/hero.jpg
|
237
|
+
```
|
238
|
+
|
239
|
+
In Sprockets, `main.scss` can reference `hero.jpg` like this:
|
240
|
+
```css
|
241
|
+
background: image_url('hero.jpg')
|
242
|
+
```
|
243
|
+
|
244
|
+
Using the same path with `url` in Propshaft will cause it to raise an error, saying it cannot locate `theme/hero.jpg`. That's because Propshaft assumes all paths are relative to the path of the file it's processing. Since it was processing a css file inside the `theme` folder, it will also look for `hero.jpg` in the same folder.
|
245
|
+
|
246
|
+
By adding a `/` at the start of the path we are telling Propshaft to consider this path as an absolute path. While this change in behavior increases the work a bit when upgrading, it makes **external libraries like FontAwesome and Bootstrap themes work out-of-the-box**.
|
247
|
+
|
248
|
+
### Asset content
|
249
|
+
|
250
|
+
It's a common pattern in apps to inline small SVG files and low resolution versions of images that need to be displayed as quickly as possible. In Propshaft, the same line of code works for all environments:
|
251
|
+
```ruby
|
252
|
+
Rails.application.assets.load_path.find('logo.svg').content
|
253
|
+
```
|
254
|
+
|
255
|
+
As Rails escapes html tags in views by default, in order to output a rendered svg you will need to specify rails not to escape the string using [html_safe](https://api.rubyonrails.org/classes/String.html#method-i-html_safe) or [raw](https://api.rubyonrails.org/classes/ActionView/Helpers/OutputSafetyHelper.html#method-i-raw).
|
256
|
+
```ruby
|
257
|
+
Rails.application.assets.load_path.find('logo.svg').content.html_safe
|
258
|
+
raw Rails.application.assets.load_path.find('logo.svg').content
|
259
|
+
```
|
260
|
+
|
261
|
+
### Precompilation in development
|
262
|
+
|
263
|
+
Propshaft uses a dynamic assets resolver in development mode. However, when you run `assets:precompile` locally Propshaft will then switch to a static assets resolver. Therefore, changes to assets will not be observed anymore and you will have to precompile the assets each time changes are made. This is different to Sprockets.
|
264
|
+
|
265
|
+
If you wish to have dynamic assets resolver enabled again, you need to clean your target folder (usually `public/assets`) and propshaft will start serving dynamic content from source. One way to do this is to run `rails assets:clobber`.
|
266
|
+
|
267
|
+
Another way to watch changes in your CSS & JS assets is by running `bin/dev` command instead of `rails server` that not only runs the server but also keeps looking for any changes in the assets and once it detects any changes, it compiles them while the server is running. This is possible because of the `Procfile.dev`.
|
268
|
+
|
269
|
+
## 4. Specific Configuration for Test Environments
|
270
|
+
|
271
|
+
### Understanding Propshaft's Test Mode
|
272
|
+
|
273
|
+
Propshaft automatically configures itself for test environments with these defaults:
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
# Automatically enabled in test environment
|
277
|
+
config.assets.server = Rails.env.test? # true for test environment
|
278
|
+
config.assets.sweep_cache = false # Disabled for faster tests
|
279
|
+
```
|
280
|
+
|
281
|
+
### Test Environment Configuration
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
# config/environments/test.rb
|
285
|
+
Rails.application.configure do
|
286
|
+
# Asset server is automatically enabled - no precompilation needed
|
287
|
+
config.assets.server = true
|
288
|
+
|
289
|
+
# Optional: Add test-specific asset paths
|
290
|
+
config.assets.paths << Rails.root.join('spec/fixtures/assets')
|
291
|
+
|
292
|
+
# Optional: Disable SRI for faster test execution
|
293
|
+
config.assets.integrity_hash_algorithm = nil
|
294
|
+
|
295
|
+
# Optional: Customize asset prefix for isolated testing
|
296
|
+
# config.assets.prefix = '/test-assets'
|
297
|
+
|
298
|
+
# Performance: Use faster file watcher (if using listen gem)
|
299
|
+
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
|
300
|
+
end
|
301
|
+
```
|
302
|
+
|
303
|
+
### Testing Asset Integration
|
304
|
+
|
305
|
+
#### RSpec Configuration
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
# spec/rails_helper.rb
|
309
|
+
RSpec.configure do |config|
|
310
|
+
# Ensure assets are available in feature specs
|
311
|
+
config.before(:suite) do
|
312
|
+
# Warm up asset cache for faster test execution
|
313
|
+
Rails.application.assets.load_path.assets
|
314
|
+
end
|
315
|
+
|
316
|
+
# Clean up assets between tests if needed
|
317
|
+
config.after(:each) do
|
318
|
+
# Only if you modify asset paths during tests
|
319
|
+
# Rails.application.assets.load_path.clear_cache
|
320
|
+
end
|
321
|
+
end
|
322
|
+
```
|
323
|
+
|
324
|
+
#### Testing Asset Helpers
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
# spec/helpers/application_helper_spec.rb
|
328
|
+
RSpec.describe ApplicationHelper, type: :helper do
|
329
|
+
describe "asset helpers" do
|
330
|
+
it "resolves asset paths correctly" do
|
331
|
+
expect(helper.asset_path('application.js')).to match(%r{^/assets/application-\w+\.js$})
|
332
|
+
end
|
333
|
+
|
334
|
+
it "includes integrity hashes when configured" do
|
335
|
+
allow(Rails.application.config.assets).to receive(:integrity_hash_algorithm).and_return('sha384')
|
336
|
+
result = helper.javascript_include_tag('application', integrity: true)
|
337
|
+
expect(result).to include('integrity="sha384-')
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
```
|
342
|
+
|
343
|
+
#### Feature Spec Asset Testing
|
344
|
+
|
345
|
+
```ruby
|
346
|
+
# spec/features/assets_spec.rb
|
347
|
+
RSpec.describe "Asset loading", type: :feature do
|
348
|
+
it "serves JavaScript assets correctly" do
|
349
|
+
visit root_path
|
350
|
+
expect(page).to have_css('script[src*="/assets/application-"]')
|
351
|
+
end
|
352
|
+
|
353
|
+
it "serves CSS assets correctly" do
|
354
|
+
visit root_path
|
355
|
+
expect(page).to have_css('link[href*="/assets/application-"][rel="stylesheet"]')
|
356
|
+
end
|
357
|
+
end
|
358
|
+
```
|
359
|
+
|
360
|
+
### Common Test Environment Issues and Solutions
|
361
|
+
|
362
|
+
#### Issue 1: Assets Not Found in Tests
|
363
|
+
**Symptom**: `Propshaft::MissingAssetError` in test environment
|
364
|
+
**Solution**:
|
365
|
+
```ruby
|
366
|
+
# Ensure asset server is enabled in test.rb
|
367
|
+
config.assets.server = true
|
368
|
+
|
369
|
+
# Check that build artifacts exist
|
370
|
+
# For jsbundling-rails/cssbundling-rails:
|
371
|
+
bundle exec rake assets:precompile # If assets need building
|
372
|
+
```
|
373
|
+
|
374
|
+
#### Issue 2: Slow Test Startup
|
375
|
+
**Symptom**: Tests take long to start due to asset discovery
|
376
|
+
**Solution**:
|
377
|
+
```ruby
|
378
|
+
# config/environments/test.rb
|
379
|
+
# Disable sweep_cache (should be default)
|
380
|
+
config.assets.sweep_cache = false
|
381
|
+
|
382
|
+
# Exclude unnecessary paths
|
383
|
+
config.assets.excluded_paths += [
|
384
|
+
Rails.root.join("app/assets/stylesheets"), # If using cssbundling
|
385
|
+
Rails.root.join("app/javascript") # If using jsbundling
|
386
|
+
]
|
387
|
+
```
|
388
|
+
|
389
|
+
#### Issue 3: Inconsistent Asset Paths Between Environments
|
390
|
+
**Symptom**: Tests pass but development/production fails with asset references
|
391
|
+
**Solution**:
|
392
|
+
```ruby
|
393
|
+
# Use consistent asset path helpers across environments
|
394
|
+
# In views, always use:
|
395
|
+
<%= asset_path('image.png') %> # Good
|
396
|
+
# Instead of:
|
397
|
+
"/assets/image.png" # Bad - won't work with digests
|
398
|
+
```
|
399
|
+
|
400
|
+
### Performance Optimization for Tests
|
401
|
+
|
402
|
+
#### Precompile Once Strategy
|
403
|
+
For CI/CD environments where you can precompile once:
|
404
|
+
|
405
|
+
```bash
|
406
|
+
# In CI setup
|
407
|
+
bundle exec rake assets:precompile
|
408
|
+
RAILS_ENV=test bundle exec rspec
|
409
|
+
```
|
410
|
+
|
411
|
+
#### Asset Path Caching
|
412
|
+
```ruby
|
413
|
+
# config/initializers/assets.rb (test environment)
|
414
|
+
if Rails.env.test?
|
415
|
+
# Warm asset cache on initialization to avoid repeated discovery
|
416
|
+
Rails.application.config.after_initialize do
|
417
|
+
Rails.application.assets.load_path.assets
|
418
|
+
end
|
419
|
+
end
|
420
|
+
```
|
421
|
+
|
422
|
+
### Integration with Test Coverage Tools
|
423
|
+
|
424
|
+
#### SimpleCov Configuration
|
425
|
+
```ruby
|
426
|
+
# spec/spec_helper.rb
|
427
|
+
require 'simplecov'
|
428
|
+
SimpleCov.start 'rails' do
|
429
|
+
# Exclude built assets from coverage
|
430
|
+
add_filter 'app/assets/builds/'
|
431
|
+
add_filter 'vendor/assets/'
|
432
|
+
end
|
433
|
+
```
|
434
|
+
|
435
|
+
### Docker and Containerized Testing
|
436
|
+
|
437
|
+
#### Dockerfile Considerations
|
438
|
+
```dockerfile
|
439
|
+
# Dockerfile
|
440
|
+
FROM ruby:3.2
|
441
|
+
|
442
|
+
# Install Node.js for asset building
|
443
|
+
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
|
444
|
+
RUN apt-get install -y nodejs
|
445
|
+
|
446
|
+
# Install dependencies
|
447
|
+
COPY Gemfile Gemfile.lock package.json package-lock.json ./
|
448
|
+
RUN bundle install && npm install
|
449
|
+
|
450
|
+
# Copy source
|
451
|
+
COPY . .
|
452
|
+
|
453
|
+
# Build assets once for all test runs
|
454
|
+
RUN bundle exec rake assets:precompile
|
455
|
+
|
456
|
+
# Run tests
|
457
|
+
CMD ["bundle", "exec", "rspec"]
|
458
|
+
```
|
459
|
+
|
460
|
+
### Migration Testing Strategy
|
461
|
+
|
462
|
+
#### Before/After Asset Comparison
|
463
|
+
```ruby
|
464
|
+
# spec/migration/sprockets_to_propshaft_spec.rb
|
465
|
+
RSpec.describe "Sprockets to Propshaft migration" do
|
466
|
+
let(:expected_assets) do
|
467
|
+
%w[application.js application.css logo.png favicon.ico]
|
468
|
+
end
|
469
|
+
|
470
|
+
it "serves all expected assets" do
|
471
|
+
expected_assets.each do |asset|
|
472
|
+
expect(Rails.application.assets.resolver.resolve(asset)).to be_present
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
it "maintains asset content integrity" do
|
477
|
+
# Test that specific assets contain expected content
|
478
|
+
asset = Rails.application.assets.load_path.find('application.js')
|
479
|
+
expect(asset.content).to include('expected_javascript_content')
|
480
|
+
end
|
481
|
+
end
|
482
|
+
```
|
483
|
+
|
484
|
+
This comprehensive guide covers the complete migration from Sprockets to Propshaft with special attention to test environment configuration and common pitfalls.
|