hot-glue 0.5.7 → 0.5.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -1
- data/.gitignore +2 -1
- data/Gemfile +1 -1
- data/LICENSE +12 -5
- data/README.md +323 -143
- data/app/helpers/hot_glue/controller_helper.rb +9 -6
- data/lib/generators/hot_glue/direct_upload_install_generator.rb +47 -0
- data/lib/generators/hot_glue/dropzone_install_generator.rb +39 -0
- data/lib/generators/hot_glue/layout/builder.rb +15 -7
- data/lib/generators/hot_glue/layout_strategy/base.rb +2 -0
- data/lib/generators/hot_glue/layout_strategy/bootstrap.rb +16 -3
- data/lib/generators/hot_glue/markup_templates/erb.rb +186 -127
- data/lib/generators/hot_glue/scaffold_generator.rb +269 -142
- data/lib/generators/hot_glue/templates/controller.rb.erb +19 -11
- data/lib/generators/hot_glue/templates/erb/_list.erb +19 -6
- data/lib/generators/hot_glue/templates/erb/_show.erb +6 -4
- data/lib/generators/hot_glue/templates/javascript/dropzone_controller.js +191 -0
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +31 -13
- data/lib/hotglue/version.rb +1 -1
- data/script/clean_generated_code +1 -1
- metadata +7 -4
data/README.md
CHANGED
@@ -20,7 +20,7 @@ Hot Glue generates functionality that is quick and dirty. It lets you be crafty.
|
|
20
20
|
* Automatically reads your models (make them, add relationships, **and** migrate your database before building your scaffolding!)
|
21
21
|
* Excellent for CREATE-READ-UPDATE-DELETE (CRUD), lists with pagination
|
22
22
|
* Great for prototyping, but you should learn Rails fundamentals first.
|
23
|
-
* 'Packaged' with Devise, Kaminari, Rspec
|
23
|
+
* 'Packaged' with Devise, Kaminari, Rspec
|
24
24
|
* Create system specs automatically along with the generated code.
|
25
25
|
* Nest your routes model-by-model for built-in poor man's authentication.
|
26
26
|
* Throw the scaffolding away when your app is ready to graduate to its next phase.
|
@@ -38,10 +38,10 @@ Other than the opinionated differences and additional features, Hot Glue produce
|
|
38
38
|
|
39
39
|
# Get Hot Glue
|
40
40
|
|
41
|
-
## [GET THE COURSE TODAY](https://
|
41
|
+
## [GET THE COURSE TODAY](https://school.jasonfleetwoodboldt.com/8188/?utm_source=github.com&utm_campaign=github_hot_glue_readme_page) **only $60 USD!**
|
42
42
|
|
43
43
|
|
44
|
-
[![Hot Glue Course](https://user-images.githubusercontent.com/59002/189544503-6edbcd40-1728-4b13-ac9a-c7772ccb8284.jpg)](https://
|
44
|
+
[![Hot Glue Course](https://user-images.githubusercontent.com/59002/189544503-6edbcd40-1728-4b13-ac9a-c7772ccb8284.jpg)](https://school.jasonfleetwoodboldt.com/8188?utm_source=github.com&utm_campaign=github_hot_glue_readme_page)
|
45
45
|
|
46
46
|
---
|
47
47
|
---
|
@@ -62,106 +62,59 @@ Instantly get a simple CRUD interface
|
|
62
62
|
|
63
63
|
_If you are on Rails 6, see [LEGACY SETUP FOR RAILS 6](https://github.com/jasonfb/hot-glue/README2.md) and complete those steps FIRST._
|
64
64
|
|
65
|
+
## The Super-Quick Setup
|
66
|
+
|
67
|
+
https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-quick-scripts/
|
68
|
+
|
69
|
+
Copy & paste the whole code block from each section into your terminal. (Pick only ONE option for each section.)
|
70
|
+
|
71
|
+
|
72
|
+
From section #1 (`rails new`), choose either (1) ImportMap Rails, (2) JSBundling, or (3) Shakapacker.
|
73
|
+
|
74
|
+
For Hot Glue, you will need:
|
75
|
+
|
76
|
+
Section #1 is to create a new Rails app. (Or you can do that yourself.)
|
77
|
+
|
78
|
+
Section #2 is to setup Rspec, FactoryBot, and Faker.
|
79
|
+
|
80
|
+
Section #4 is optional but highly recommended.
|
81
|
+
|
82
|
+
Section #5 is where you will pick a CSS Framework (Bootstrap, Tailwind, or none)
|
83
|
+
|
84
|
+
Section #6 is for two support gems (Kaminari) for Hot Glue
|
65
85
|
|
66
|
-
|
86
|
+
Section #7 is for Hot Glue itself
|
67
87
|
|
68
|
-
|
88
|
+
You will also need section #8 to setup Devise if you want authentication.
|
69
89
|
|
70
|
-
For reference, see https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-do-i-need-importmap-rails/
|
71
90
|
|
72
|
-
|
91
|
+
## Step-By-Step Setup
|
92
|
+
|
93
|
+
### 1. RAILS NEW
|
94
|
+
To understand the options for `rails new`, see [this post](https://jasonfleetwoodboldt.com/courses/rails-7-crash-course/rails-7-bootstrap/)
|
95
|
+
|
96
|
+
It is important that you know what kind of app you are creating (Importmap, JSBundling, or Shakapacker) because there are specific differences in how you will work with them. (Hot Glue is compatible with all 3 paradigms, but if you don't take the time to understand the setup, you will be confused as to why things aren't working.)
|
97
|
+
|
98
|
+
To run Turbo (which Hot Glue requires), you must either (1) be running an ImportMap-Rails app, or (2) be running a Node-compiled app using any of JSBundling, Shakapacker, or its alternatives.
|
73
99
|
|
74
100
|
(1) To use ImportMap Rails, start with
|
75
|
-
`rails new`
|
101
|
+
`rails new MyGreatApp`
|
76
102
|
|
77
103
|
(For full instructions to install Bootstrap with Importmap, check out [these instructions](https://jasonfleetwoodboldt.com/courses/stepping-up-rails/importmap-rails-with-bootstrap-sprockets-stimulus-and-turbo-long-tutorial/))
|
78
104
|
|
79
105
|
(2) To use JSBundling, start with
|
80
|
-
`rails new --javascript=
|
106
|
+
`rails new MyGreatApp --javascript=esbuild`
|
81
107
|
|
82
108
|
|
83
109
|
**If using JSBundling, make sure to use the new `./bin/dev` to start your server instead of the old `rails server` or else your Turbo interactions will not work correctly.**
|
84
110
|
(If you want Bootstrap for a JSBundling app, install it following [these instructions](https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-up-running-with-jsbundling-esbuild-stimulus-turbo-bootstrap-circleci/))
|
85
111
|
|
86
|
-
(3) To use Shakapacker, start with `rails new --skip-javascript` and [see this post](https://jasonfleetwoodboldt.com/courses/react-heart-rails/rails-7-shakapacker-and-reactonrails-quick-setup-part-1/)
|
112
|
+
(3) To use Shakapacker, start with `rails new MyGreatApp --skip-javascript` and [see this post](https://jasonfleetwoodboldt.com/courses/react-heart-rails/rails-7-shakapacker-and-reactonrails-quick-setup-part-1/)
|
87
113
|
|
88
114
|
(For the old method of installing Bootstrap [see this post](https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-bootstrap/))
|
89
115
|
|
90
116
|
(Remember, for Rails 6 you must go through the [LEGACY SETUP FOR RAILS 6](https://github.com/jasonfb/hot-glue/blob/main/README2.md) before continuing.)
|
91
117
|
|
92
|
-
If you doing the 'Super-Quick Setup', you can skip the additional blog posts linked above because the steps in them are covered in the shell script(s) below.
|
93
|
-
|
94
|
-
## The Super-Quick Setup
|
95
|
-
|
96
|
-
Be sure to do `git add .` and `git commit -m "initial commit"` after creating your new Rails 7 app.
|
97
|
-
|
98
|
-
```
|
99
|
-
bundle add rspec-rails factory_bot_rails ffaker --group "development, test" &&
|
100
|
-
git add . && git commit -m "adds gems" &&
|
101
|
-
rails generate rspec:install &&
|
102
|
-
git add . && git commit -m "adds rspec" &&
|
103
|
-
rm app/assets/stylesheets/application.css &&
|
104
|
-
echo "" > app/assets/stylesheets/application.scss &&
|
105
|
-
sed -i '' -e 's/# gem "sassc-rails"//g' Gemfile && sed -i '' -e 's/# Use Sass to process CSS//g' Gemfile &&
|
106
|
-
bundle install && bundle add sassc-rails && git add . && git commit -m "adds sassc-rails" &&
|
107
|
-
rm -rf test/ && git add . && git commit -m "removes minitest" &&
|
108
|
-
bundle add hot-glue && git add . && git commit -m "adds hot-glue" &&
|
109
|
-
rails generate hot_glue:install --layout=bootstrap &&
|
110
|
-
git add . && git commit -m "hot glue setup" &&
|
111
|
-
bundle add bootstrap &&
|
112
|
-
echo "\n@import 'bootstrap';\n" >> app/assets/stylesheets/application.scss
|
113
|
-
sed -i '' -e 's/# Rails.application.config.assets.precompile += %w( admin.js admin.css )/Rails.application.config.assets.precompile += %w( application.scss )/g' config/initializers/assets.rb &&
|
114
|
-
sed -i '' -e 's/Rails.application.configure do/Rails.application.configure do\n config.sass.inline_source_maps = true/g' config/environments/development.rb
|
115
|
-
git add . && git commit -m "bootstrap install" &&
|
116
|
-
bundle add font_awesome5_rails &&
|
117
|
-
echo "\n@import 'font_awesome5_webfont';\n" >> app/assets/stylesheets/application.scss
|
118
|
-
git add . && git commit -m "adds fontawesome" &&
|
119
|
-
bundle add kaminari &&
|
120
|
-
rails generate kaminari:views bootstrap4 &&
|
121
|
-
git add . && git commit -m "adding kaminari and views" &&
|
122
|
-
bundle add devise && bundle install &&
|
123
|
-
git add . && git commit -m "adding devise gem" &&
|
124
|
-
rails generate devise:install &&
|
125
|
-
rails g devise:views &&
|
126
|
-
sed -i '' -e 's/Rails.application.configure do/Rails.application.configure do\n config.action_mailer.default_url_options = { host: "localhost", port: 3000 }/g' config/environments/development.rb &&
|
127
|
-
sed -i '' -e 's/# root "articles#index"//g' config/routes.rb &&
|
128
|
-
sed -i '' -e 's/Rails.application.routes.draw do/Rails.application.routes.draw do\n root to: "welcome#index"/g' config/routes.rb &&
|
129
|
-
git add . && git commit -m 'devise view fixes' &&
|
130
|
-
rails generate controller Welcome &&
|
131
|
-
sed -i '' -e 's/class WelcomeController < ApplicationController/class WelcomeController < ApplicationController\n def index\n\n end/g' app/controllers/welcome_controller.rb &&
|
132
|
-
echo "hello world" > app/views/welcome/index.erb &&
|
133
|
-
git add . && git commit -m "generates Welcome controller" &&
|
134
|
-
sed -i '' -e 's/html: { method: :post }/html: { method: :post, 'data-turbo': false}/g' app/views/devise/confirmations/new.html.erb &&
|
135
|
-
sed -i '' -e 's/ url: session_path(resource_name))/ url: session_path(resource_name), html: {"data-turbo": false})/g' app/views/devise/sessions/new.html.erb &&
|
136
|
-
sed -i '' -e 's/ url: registration_path(resource_name))/ url: registration_path(resource_name), html: {"data-turbo": false})/g' app/views/devise/registrations/new.html.erb &&
|
137
|
-
sed -i '' -e 's/, html: { method: :post })/, html: { method: :post, "data-turbo": false })/g' app/views/devise/passwords/new.html.erb &&
|
138
|
-
git add . && git commit -m 'devise view fixes' &&
|
139
|
-
rails generate model User name:string &&
|
140
|
-
rails generate devise User && git add . && git commit -m "adds Users model with devise" &&
|
141
|
-
&& ./bin/setup && rails db:migrate &&
|
142
|
-
git add . && git commit -m "schema file"
|
143
|
-
```
|
144
|
-
|
145
|
-
|
146
|
-
For Importmap apps:
|
147
|
-
```
|
148
|
-
./bin/importmap pin "bootstrap@5.1.3" &&
|
149
|
-
./bin/importmap pin "@popperjs/core@2.11.2" &&
|
150
|
-
git add . && git commit -m "pinning boostrap and popper js for bootstrap"
|
151
|
-
```
|
152
|
-
|
153
|
-
For JSBundling & Shakapacker:
|
154
|
-
```
|
155
|
-
echo "\ncss: yarn build:css --watch\n" >> Procfile.dev &&
|
156
|
-
yarn add @popperjs/core bootstrap bootstrap-icons sass &&
|
157
|
-
sed -i '' -e 's/\/\/= link_directory ..\/stylesheets .css//g' app/assets/config/manifest.js &&
|
158
|
-
sed -i '' -e 's/ "scripts": {/ "scripts": {\n "build:css": "sass .\/app\/assets\/stylesheets\/application.scss:.\/app\/assets\/builds\/application.css --no-source-map --load-path=node_modules",/g' package.json &&
|
159
|
-
yarn install &&
|
160
|
-
git add . && git commit -m "adding bootstrap packages"
|
161
|
-
```
|
162
|
-
|
163
|
-
|
164
|
-
## Step-By-Step Setup
|
165
118
|
|
166
119
|
### 2. ADD RSPEC, FACTORY-BOT, AND FFAKER
|
167
120
|
|
@@ -180,9 +133,16 @@ end
|
|
180
133
|
|
181
134
|
- Because you are not using Minitest, you can delete the `test/` folder at the root of your repository.
|
182
135
|
|
136
|
+
### 3. CSS Bundling Rails (optional)
|
137
|
+
|
138
|
+
```
|
139
|
+
bundle add cssbundling-rails
|
140
|
+
./bin/rails css:install:bootstrap
|
141
|
+
```
|
183
142
|
|
184
143
|
|
185
|
-
|
144
|
+
|
145
|
+
### 4. HOTGLUE INSTALLER
|
186
146
|
Add `gem 'hot-glue'` to your Gemfile & `bundle install`
|
187
147
|
|
188
148
|
During in installation, you MUST supply a `--layout` flag.
|
@@ -212,29 +172,20 @@ default is `erb`. IMPORTANT: As of right now, HAML and SLIM are not currently su
|
|
212
172
|
|
213
173
|
|
214
174
|
#### example installing ERB using Bootstrap layout:
|
215
|
-
|
175
|
+
`./bin/rails generate hot_glue:install --markup=erb --layout=bootstrap`
|
216
176
|
|
217
177
|
#### Example installing using Hot Glue layout and the 'like_mountain_view' (Gmail-inspired) theme:
|
218
178
|
`rails generate hot_glue:install --markup=erb --layout=hotglue --theme=like_mountain_view`
|
219
179
|
|
220
180
|
The Hot Glue installer did several things for you in this step. Examine the git diffs or see 'Hot Glue Installer Notes' below.
|
221
181
|
|
222
|
-
|
223
|
-
### 4. Font-awesome (optional)
|
224
|
-
|
225
|
-
I recommend
|
226
|
-
https://github.com/tomkra/font_awesome5_rails
|
227
|
-
or
|
228
|
-
https://github.com/FortAwesome/font-awesome-sass
|
229
|
-
|
230
|
-
|
231
|
-
### 5. Devise
|
182
|
+
### 4. Devise
|
232
183
|
(If you are on Rails 6, you must do ALL of the steps in the Legacy Setup steps. Be sure not to skip **Legacy Step #5** below)
|
233
184
|
https://github.com/jasonfb/hot-glue/blob/main/README2.md
|
234
185
|
|
235
186
|
You MUST run the installer FIRST or else you will put your app into a non-workable state:
|
236
187
|
```
|
237
|
-
rails generate devise:install
|
188
|
+
./bin/rails generate devise:install
|
238
189
|
```
|
239
190
|
|
240
191
|
IMPORTANT: Follow the instructions the Devise installer gives you, *Except Step 3*, you can skip this step:
|
@@ -249,7 +200,7 @@ IMPORTANT: Follow the instructions the Devise installer gives you, *Except Step
|
|
249
200
|
|
250
201
|
Be sure to create primary auth model with:
|
251
202
|
|
252
|
-
|
203
|
+
`./bin/rails generate devise User name:string`
|
253
204
|
|
254
205
|
Remember, you don't need to tell Devise that your User has an email, an encrypted password, a reset token, and a 'remember me' flag to let the user stay logged in.
|
255
206
|
|
@@ -257,21 +208,7 @@ Those features come by default with Devise, and you'll find the fields for them
|
|
257
208
|
|
258
209
|
In this example above, you are creating all of those fields along with a simple 'name' (string) field for your User table.
|
259
210
|
|
260
|
-
|
261
|
-
!!! Warning: as of 2022-09-19, Devise is still not compatible out-of-the-box with Rails Turbo.
|
262
|
-
|
263
|
-
To fix this, run
|
264
|
-
`rails generate devise:views`
|
265
|
-
|
266
|
-
|
267
|
-
Then manually add `html: {'data-turbo' => "false"}` to all of the Devise forms. You will need to edit the following forms:
|
268
|
-
`views/devise/sessions/new.html.erb`, `views/devise/registrations/edit.html.erb`,
|
269
|
-
`views/devise/registrations/new.html.erb`, and
|
270
|
-
|
271
|
-
Add the data-turbo false option in the html key of the form, shown in bold here:
|
272
|
-
|
273
|
-
form_for(resource, as: resource_name, **html: {'data-turbo' => "false"},** url: session_path(resource_name) ) do |f|
|
274
|
-
|
211
|
+
Devise 4.9.0 is now fully compatible with Rails 7.
|
275
212
|
|
276
213
|
#### Hot Glue Installer Notes
|
277
214
|
|
@@ -367,7 +304,7 @@ Alternatively, you can define your own driver like so:
|
|
367
304
|
TitleCase class name of the thing you want to build a scaffoling for.
|
368
305
|
|
369
306
|
```
|
370
|
-
rails generate hot_glue:scaffold Thing
|
307
|
+
./bin/rails generate hot_glue:scaffold Thing
|
371
308
|
```
|
372
309
|
|
373
310
|
(note: Your `Thing` object must `belong_to` an authenticated `User` or alternatively you must create a Gd controller, see below.)
|
@@ -381,7 +318,7 @@ All options begin with two dashes (`--`) and a followed by an `=` and a value
|
|
381
318
|
pass `--namespace=` as an option to denote a namespace to apply to the Rails path helpers
|
382
319
|
|
383
320
|
|
384
|
-
|
321
|
+
`./bin/rails generate hot_glue:scaffold Thing --namespace=dashboard`
|
385
322
|
|
386
323
|
This produces several views at `app/views/dashboard/things/` and a controller at`app/controllers/dashboard/things_controller.rb`
|
387
324
|
|
@@ -413,9 +350,9 @@ resources :invoices do
|
|
413
350
|
end
|
414
351
|
```
|
415
352
|
|
416
|
-
|
353
|
+
`./bin/rails generate hot_glue:scaffold Invoice`
|
417
354
|
|
418
|
-
|
355
|
+
`./bin/rails generate hot_glue:scaffold Line --nested=invoice`
|
419
356
|
|
420
357
|
|
421
358
|
Remember, nested should match how the hierarchy of nesting is in your `routes.rb` file. (Which Hot Glue does not create or edit for you.)
|
@@ -437,11 +374,11 @@ end
|
|
437
374
|
|
438
375
|
_For multi-level nesting use slashes to separate your levels of nesting._
|
439
376
|
|
440
|
-
|
377
|
+
`./bin/rails generate hot_glue:scaffold Invoice`
|
441
378
|
|
442
|
-
|
379
|
+
`./bin/rails generate hot_glue:scaffold Line --nested=invoice`
|
443
380
|
|
444
|
-
|
381
|
+
`./bin/rails generate hot_glue:scaffold Charge --nested=invoice/line`
|
445
382
|
|
446
383
|
|
447
384
|
|
@@ -483,8 +420,8 @@ end
|
|
483
420
|
Even though we have two routes pointed to **invoices**, both will go to the same controller (`app/controllers/admin/invoices_controller.rb`)
|
484
421
|
|
485
422
|
```
|
486
|
-
rails generate hot_glue:scaffold User --namespace=admin --gd
|
487
|
-
rails generate hot_glue:scaffold Invoice --namespace=admin --gd --nested=~users
|
423
|
+
./bin/rails generate hot_glue:scaffold User --namespace=admin --gd
|
424
|
+
./bin/rails generate hot_glue:scaffold Invoice --namespace=admin --gd --nested=~users
|
488
425
|
```
|
489
426
|
Notice for the Invoice build, the parent user is *optionalized* (not 'optional'-- optionalized: to be made so it can be made optional).
|
490
427
|
|
@@ -506,7 +443,7 @@ If you use Devise, you probably already have a `current_user` method available i
|
|
506
443
|
|
507
444
|
If you use a different object other than "User" for authentication, override using the `auth` option.
|
508
445
|
|
509
|
-
|
446
|
+
`./bin/rails generate hot_glue:scaffold Thing --auth=current_account`
|
510
447
|
|
511
448
|
You will note that in this example it is presumed that the Account object will have an association for `things`
|
512
449
|
|
@@ -545,7 +482,7 @@ As well, the `after_sign_in_path_for(user)` here is a hook for Devise also that
|
|
545
482
|
The default (do not pass `auth_identifier=`) will match the `auth` (So if you use 'account' as the auth, `authenticate_account!` will get invoked from your generated controller; the default is always 'user', so you can leave both auth and auth_identifier off if you want 'user')
|
546
483
|
|
547
484
|
|
548
|
-
|
485
|
+
`./bin/rails generate hot_glue:scaffold Thing --auth=current_account --auth_identifier=login`
|
549
486
|
|
550
487
|
|
551
488
|
In this example, the controller produced with:
|
@@ -559,7 +496,7 @@ However, the object graph anchors would continue to start from current_account.
|
|
559
496
|
|
560
497
|
Use empty string to **turn this method off**:
|
561
498
|
|
562
|
-
|
499
|
+
`./bin/rails generate hot_glue:scaffold Thing --auth=current_account --auth_identifier=''`
|
563
500
|
|
564
501
|
In this case a controller would be generated that would have NO before_action to authenticate the account, but it would still treat the current_account as the auth root for the purpose of loading the objects.
|
565
502
|
|
@@ -580,7 +517,7 @@ The short form looks like this. It presumes there is a 'pets' association from `
|
|
580
517
|
|
581
518
|
(The long form equivalent of this would be `--hawk=pet_id{current_user.pets}`)
|
582
519
|
|
583
|
-
This is covered in [Example #3 in the Hot Glue Tutorial](https://
|
520
|
+
This is covered in [Example #3 in the Hot Glue Tutorial](https://school.jasonfleetwoodboldt.com/8188)
|
584
521
|
|
585
522
|
To hawk to a scope that is not the currently authenticated user, use the long form with `{...}`
|
586
523
|
to specify the scope. Be sure to note to add the association name itself, like `users`:
|
@@ -590,7 +527,7 @@ to specify the scope. Be sure to note to add the association name itself, like `
|
|
590
527
|
This would hawk the Appointment's `user_id` key to any users who are within the scope of the
|
591
528
|
current_user's has_many association (so, for any other "my" family, would be `current_user.family.users`).
|
592
529
|
|
593
|
-
This is covered in [Example #4 in the Hot Glue Tutorial](https://
|
530
|
+
This is covered in [Example #4 in the Hot Glue Tutorial](https://school.jasonfleetwoodboldt.com/8188)
|
594
531
|
|
595
532
|
|
596
533
|
### `--plural=`
|
@@ -598,11 +535,11 @@ This is covered in [Example #4 in the Hot Glue Tutorial](https://jfb.teachable.c
|
|
598
535
|
You don't need this if the pluralized version is just + "s" of the singular version.
|
599
536
|
Only use for non-standard plurlizations, and be sure to pass it as TitleCase (as if you pluralized the model name which is non-standard for Rails)
|
600
537
|
|
601
|
-
An better alternative is to define the non-standard plurlizations globally in your app.
|
538
|
+
An better alternative is to define the non-standard plurlizations globally in your app, which Hot Glue will respect.
|
602
539
|
|
603
540
|
Make a file at `config/initializers/inflections.rb`
|
604
|
-
|
605
|
-
|
541
|
+
|
542
|
+
Add new inflection rules using the following format:
|
606
543
|
```
|
607
544
|
ActiveSupport::Inflector.inflections do |inflect|
|
608
545
|
inflect.irregular 'clothing', 'clothes'
|
@@ -621,7 +558,7 @@ By default, all fields are included unless they are on the default exclude list.
|
|
621
558
|
If you specify any exclude list, those excluded **and** the default exclude list will be excluded. (If you need any of the fields on the default exclude list, you must use `--include` instead.)
|
622
559
|
|
623
560
|
|
624
|
-
|
561
|
+
`./bin/rails generate hot_glue:scaffold Account --exclude=password`
|
625
562
|
|
626
563
|
|
627
564
|
### `--include=`
|
@@ -629,7 +566,7 @@ Separate field names by COMMA
|
|
629
566
|
|
630
567
|
If you specify an include list, it will be treated as a whitelist: no fields will be included unless specified on the include list.
|
631
568
|
|
632
|
-
|
569
|
+
`./bin/rails generate hot_glue:scaffold Account --include=first_name,last_name,company_name,created_at,kyc_verified_at`
|
633
570
|
|
634
571
|
You may not specify both include and exclude.
|
635
572
|
|
@@ -774,7 +711,7 @@ The bang (`!`) methods can respond in one of four ways:
|
|
774
711
|
|
775
712
|
This means you can be a somewhat lazy about your bang methods, but keep in mind the truth operator compares boolean true NOT any object is truth. So your return object must either be actually true (boolean), or an object that is string or string-like (responds to .to_s). Want to just say it didn’t work? Return false. Want to just say it was OK? Return true. Want to say it was successful but provide a more detailed response? Return a string.
|
776
713
|
|
777
|
-
Finally, you can raise an ActiveRecord error which will also get passed to the user
|
714
|
+
Finally, you can raise an ActiveRecord error which will also get passed to the user in the flash alert area.
|
778
715
|
|
779
716
|
For more information see Example 5 in the Tutorial
|
780
717
|
|
@@ -791,6 +728,9 @@ Can now be created with more space (wider) by adding a `+` to the end of the dow
|
|
791
728
|
|
792
729
|
The 'Abcs' portal will display as 5 bootstrap columns instead of the typical 4. (You may use multiple ++ to keep making it wider but the inverse with minus is not supported
|
793
730
|
|
731
|
+
### `--stacked-downnesting`
|
732
|
+
|
733
|
+
This puts the downnested portals on top of one another (stacked top to bottom) instead of side-by-side (left to right). This is useful if you have a lot of downnested portals and you want to keep the page from getting too wide.
|
794
734
|
|
795
735
|
|
796
736
|
## FLAGS (Options with no values)
|
@@ -853,7 +793,7 @@ To do this, use flag `--display-list-after-update`. The update will behave like
|
|
853
793
|
|
854
794
|
### `--with-turbo-streams`
|
855
795
|
|
856
|
-
If and only if you specify `--with-turbo-streams`, your views will contain `turbo_stream_from` directives. Whereas your views will always contain `turbo_frame_tags` (
|
796
|
+
If and only if you specify `--with-turbo-streams`, your views will contain `turbo_stream_from` directives. Whereas your views will always contain `turbo_frame_tags` (whether or not this flag is specified) and will use the Turbo stream replacement mechanism for non-idempotent actions (create & update). This flag just brings the magic of live-reload to the scaffold interfaces themselves.
|
857
797
|
|
858
798
|
**_To test_**: Open the same interface in two separate browser windows. Make an edit in one window and watch your edit appear in the other window instantly.
|
859
799
|
|
@@ -868,6 +808,7 @@ please note that *creating* and *deleting* do not yet have a full & complete imp
|
|
868
808
|
|
869
809
|
### `--alt-foreign-key-lookup` (Foreign Key Lookups)
|
870
810
|
|
811
|
+
Example #1
|
871
812
|
`--alt-foreign-key-lookup=user_id{email}`
|
872
813
|
|
873
814
|
Let's assume a `Company` `has_many :company_users` and also a `Company` `has_many :users, through: :company_users`
|
@@ -880,6 +821,19 @@ Let's say instead you don't want to expose the full list of all users to this co
|
|
880
821
|
|
881
822
|
Instead of a drop-down, the interface will present an input box for the user to supply an *search by* email.
|
882
823
|
|
824
|
+
Example #2
|
825
|
+
```
|
826
|
+
--alt-foreign-key-lookup='agent_id{email+}'
|
827
|
+
```
|
828
|
+
|
829
|
+
First, assume the current able has a `belongs_to` association for `agent_id` to a foreign model, `Agent`
|
830
|
+
|
831
|
+
Here, we would build a scaffold that would treat the foreign key `agent_id` as an alt lookup, allowing the user to search for foreign records by email (the agent's email).
|
832
|
+
|
833
|
+
The `+` symbol indicates to automatically make a new `agent` record (without it, the agent_id will be set to nil if there is no associated agent record found -- this may cause the update to fail, unless `optional: true` is on the belongs_to association.)
|
834
|
+
|
835
|
+
|
836
|
+
|
883
837
|
** Note: Current implementation does not work in conjunction with hawked associations to protect against users from accessing associated records not within scope.**
|
884
838
|
TODO: make it work with hawked associations to protect against users from accessing associated records not within scope
|
885
839
|
|
@@ -920,8 +874,6 @@ Omits list LABEL itself above the list. (Do not confuse with the list heading wh
|
|
920
874
|
Note that list labels may be automatically omitted on downnested scaffolds.
|
921
875
|
|
922
876
|
|
923
|
-
|
924
|
-
|
925
877
|
## Field Labels
|
926
878
|
|
927
879
|
### `--form-labels-position` (default: `after`; options are **before**, **after**, and **omit**)
|
@@ -956,18 +908,178 @@ Omits the heading of column names that appears above the 1st row of data.
|
|
956
908
|
|
957
909
|
## Special Features
|
958
910
|
|
911
|
+
### `--attachments`
|
912
|
+
|
913
|
+
#### ActiveStorage Quick Setup
|
914
|
+
(For complete docs, refer to https://guides.rubyonrails.org/active_storage_overview.html)
|
915
|
+
|
916
|
+
`brew install vips`
|
917
|
+
(for videos `brew install ffmpeg`)
|
918
|
+
|
919
|
+
```
|
920
|
+
bundle add image_processing
|
921
|
+
./bin/rails active_storage:install
|
922
|
+
./bin/rails db:migrate
|
923
|
+
```
|
924
|
+
|
925
|
+
Generate an images model:
|
926
|
+
|
927
|
+
`./bin/rails generate model Images name:string`
|
928
|
+
|
929
|
+
add to `app/model/image.rb`, giving it a variant called thumb (Note: Hot Glue will fallback to using a variant called "thumb" if you use the shorthand syntax. If you use the long syntax, you can specify the variant to use for displaying the image)
|
930
|
+
|
931
|
+
```
|
932
|
+
has_one_attached :avatar do |attachable|
|
933
|
+
attachable.variant :thumb, resize_to_limit: [100, 100]
|
934
|
+
end
|
935
|
+
```
|
936
|
+
Generate a Hot Glue scaffold with the attachment avatar appended to the field list (the shorthand syntax)
|
937
|
+
|
938
|
+
`./bin/rails generate hot_glue:scaffold Image --include='name:avatar' --gd --attachments='avatar'`
|
939
|
+
|
940
|
+
(Attachments behave like fields and follow the same layout rules used for fields, except that, unlike fields, when NOT using an --include list, they do not get automatically added. Thus, attachments are opt-in. You do not need to specify an attachment on the attachments list as ALSO being on the include list, but you can for the purpose of using the layout tricks discussed in Specified Grouping Mode to make the attachment appear on the layout where you want it to)
|
941
|
+
|
942
|
+
#### Caveats:
|
943
|
+
• If thumbnails aren't showing up, make sure you have
|
944
|
+
|
945
|
+
1) installed vips, and
|
946
|
+
2) used an image that supports ActiveStorage "variable" mechanism. The supported types are png, gif, jpg, pjpeg, tiff, bmp, vnd.adobe.photoshop, vnd.microsoft.icon, webp. see https://stackoverflow.com/a/61971660/3163663
|
947
|
+
To debug, make sure the object responds true to the variable? method.
|
948
|
+
|
949
|
+
If you use the shorthand syntax, Hot Glue looks for a variant "thumb" (what you see in the example above).
|
950
|
+
|
951
|
+
If it finds one, it will render thumbnails from the attachment variant `thumb`. To specify a variant name other than "thumb", use the first parameter below.
|
952
|
+
|
953
|
+
If using the shortform syntax and Hot Glue does **not find a variant** called `thumb` at the code generation time, it will build scaffolding without thumbnails.
|
954
|
+
|
955
|
+
#### `--attachments` Long form syntax with 1 parameter
|
956
|
+
|
957
|
+
**--attachments='_attachment name_{_variant name_}'**
|
958
|
+
|
959
|
+
What if your variant is called something other than `thumb`
|
960
|
+
|
961
|
+
Use the long-form syntax specifying a variant name other than `thumb`. For example, `thumbnail`
|
962
|
+
|
963
|
+
`./bin/rails generate hot_glue:scaffold Image --include='name:avatar' --gd --attachments='avatar{thumbnail}'`
|
964
|
+
|
965
|
+
The model would look like this:
|
966
|
+
```
|
967
|
+
has_one_attached :avatar do |attachable|
|
968
|
+
attachable.variant :thumbnail, resize_to_limit: [100, 100]
|
969
|
+
end
|
970
|
+
```
|
971
|
+
|
972
|
+
If using the long-form syntax with 1 parameter and Hot Glue does not find the specified variant declared in your attachment, it will stop and raise an error.
|
973
|
+
|
974
|
+
|
975
|
+
#### `--attachments` Long form syntax with 1st and 2nd parameters
|
976
|
+
|
977
|
+
**--attachments='_attachment name_{_variant name_|_field for saving original filename_}'**
|
978
|
+
|
979
|
+
Grab the original file name of the uploaded file and stick it into a field called `name`
|
980
|
+
|
981
|
+
`./bin/rails generate hot_glue:scaffold Image --include='orig_filename:avatar' --gd --attachments='avatar{thumbnail|name} --show-only=name'`
|
982
|
+
|
983
|
+
Note: You must have a string field called `orig_filename`. It does not need to be visible, but if it is, it should be part of the `--show-only` list. (If it is not part of the show-only list, Hot Glue will overwrite it every time you upload a new file, making it so that any user's change might not stick.)
|
984
|
+
|
985
|
+
Note that the `orig_filename` is not part of the inputted parameters, it simply gets appended to the model **bypassing the Rails strong parameters mechanism**, which is why it is irrelevant if it is included in the field list and recommended that if you do include it, you make it show-only so as not to allow your users to edit or modify it.
|
986
|
+
|
987
|
+
Note: The 1st and 2nd parameters may be left empty (use `||`) but the 3rd and 4th parameters must either be specified or the parameter must be left off.
|
988
|
+
|
989
|
+
#### `--attachments` Long form syntax with 1st, 2nd, and 3rd parameters
|
990
|
+
|
991
|
+
An optional 3rd parameter to the long-form syntax allows you to specify direct upload using the word "direct", which will add direct_upload: true to your f.file_field tags.
|
992
|
+
|
993
|
+
Simply specify a 3rd parameter of `direct` to enable this attachment to use direct upload.
|
994
|
+
|
995
|
+
**--attachments='avatar{thumbnail|orig_filename|direct}'**
|
996
|
+
|
997
|
+
If you leave the 2nd parameter blank when using the 3rd parameter, it will default to NOT saving the original filename:
|
998
|
+
|
999
|
+
`--attachments='avatar{thumbnail||direct}'`
|
1000
|
+
|
1001
|
+
|
1002
|
+
#### For S3 Setup
|
1003
|
+
|
1004
|
+
|
1005
|
+
```
|
1006
|
+
bundle add aws-sdk-s3
|
1007
|
+
```
|
1008
|
+
|
1009
|
+
|
1010
|
+
in `config/storage.yml`, enable this block and configure with the access key + secret associated with an AWS user that has permissions:
|
1011
|
+
|
1012
|
+
Also be sure to change `bucket`
|
1013
|
+
|
1014
|
+
```
|
1015
|
+
# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
|
1016
|
+
amazon:
|
1017
|
+
service: S3
|
1018
|
+
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
|
1019
|
+
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
|
1020
|
+
region: us-east-1
|
1021
|
+
bucket: your_bucket-<%= Rails.env %>
|
1022
|
+
|
1023
|
+
```
|
1024
|
+
|
1025
|
+
|
1026
|
+
in development.rb or production.rb (or both), set
|
1027
|
+
```
|
1028
|
+
config.active_storage.service = :amazon
|
1029
|
+
```
|
1030
|
+
|
1031
|
+
|
1032
|
+
#### For Direct Upload Support
|
1033
|
+
1.
|
1034
|
+
```
|
1035
|
+
yarn add @rails/activestorage
|
1036
|
+
```
|
1037
|
+
|
1038
|
+
2. You need a job runner like sidekiq or delayed_job. I recommend sidekiq. Make sure to have it
|
1039
|
+
|
1040
|
+
- Start sidekiq with `bundle exec sidekiq` while you are testing
|
1041
|
+
|
1042
|
+
3. Install ActiveStorage JS using:
|
1043
|
+
|
1044
|
+
`./bin/rails generate hot_glue:direct_upload_install`
|
1045
|
+
|
1046
|
+
AND be sure to use the 3rd parameter ('direct') when building a HG scaffold as explained above.
|
1047
|
+
|
1048
|
+
|
1049
|
+
#### For Dropzone support
|
1050
|
+
- Dropzone requires direct uploads, so you must have direct uploads enabled for the attachment you want to use dropzone with.
|
1051
|
+
|
1052
|
+
|
1053
|
+
- Direct uploads requires that you have configured your external storage (S3, etc) correctly. See the ActiveStorage guide.
|
1054
|
+
|
1055
|
+
`yarn add dropzone`
|
1056
|
+
|
1057
|
+
|
1058
|
+
(If you don't already have stimulus-rails, you will also need: `bundle add stimulus-rails` and `./bin/rails stimulus:install`)
|
1059
|
+
|
1060
|
+
Then run:
|
1061
|
+
```
|
1062
|
+
./bin/rails generate hot_glue:dropzone_install
|
1063
|
+
```
|
1064
|
+
This will 1) copy the dropzone_controller.js file into your app and 2) add the dropzone css into your app's application.css or application.bootstrap.css file.
|
1065
|
+
|
1066
|
+
|
1067
|
+
|
959
1068
|
|
960
1069
|
### `--factory-creation={ ... }`
|
961
1070
|
|
962
1071
|
The code you specify inside of `{` and `}` will be used to generate a new object. The factory should instantiate with any arguments (I suggest Ruby keyword arguments) and must provide a method that is the name of the thing.
|
963
1072
|
|
1073
|
+
You may use semi-colons to separate multiple lines of code.
|
1074
|
+
|
964
1075
|
For example, a user Factory might be called like so:
|
965
1076
|
|
966
|
-
|
1077
|
+
`./bin/rails generate hot_glue:scaffold User --factory-creation={factory = UserFactory.new(params: user_params)} --gd`
|
967
1078
|
|
968
1079
|
(Note we are relying on the `user_params` method provided by the controller.)
|
969
1080
|
|
970
1081
|
You must do one of two things:
|
1082
|
+
|
971
1083
|
1) In the code you specify, set an instance variable `@user` to be the newly created thing. (Your code should contain something like `@thing = ` to trigger this option.)
|
972
1084
|
2) Make a local variable called `factory` **and** have a method of the name of the object (`user`) on a local variable called `factory` that your code created
|
973
1085
|
|
@@ -999,6 +1111,18 @@ end
|
|
999
1111
|
```
|
1000
1112
|
|
1001
1113
|
|
1114
|
+
If you are using factory creation along with with alt lookups, be sure your factory code creates a local variable that follows this name
|
1115
|
+
|
1116
|
+
**<downcase association name>**_factory.<downcase association name>
|
1117
|
+
|
1118
|
+
Thus, your factory object must have a method of the same name as the factory being created which returns the thing that got created.
|
1119
|
+
(It can do the creation either on instantiation or when calling that method)
|
1120
|
+
|
1121
|
+
For example, assuming the example from above, we are going to do the lookup ourselves inside of our own `AgentFactory` object.)
|
1122
|
+
|
1123
|
+
```
|
1124
|
+
agent_factory = AgentFactory.new(find_or_create_by_email: agent_company_params[:__lookup_email])
|
1125
|
+
```
|
1002
1126
|
|
1003
1127
|
|
1004
1128
|
|
@@ -1008,6 +1132,7 @@ HotGlue will copy a file named base_controller.rb to the same folder where it tr
|
|
1008
1132
|
|
1009
1133
|
The created controller will always have this base controller as its subclass. You are encouraged to implement functionality common to the *namespace* (shared between the controllers in the namespace) using this technique.
|
1010
1134
|
|
1135
|
+
|
1011
1136
|
## Special Table Labels
|
1012
1137
|
|
1013
1138
|
If your object is very wordy (like MyGreatHook) and you want it to display in the UI as something shorter,
|
@@ -1041,6 +1166,7 @@ Child portals have the headings omitted automatically (there is a heading identi
|
|
1041
1166
|
# Note about enums
|
1042
1167
|
|
1043
1168
|
The Rails 7 enum implementation for Postgres is very slick but has a counter-intuitive facet.
|
1169
|
+
|
1044
1170
|
Define your Enums in Postgres as strings:
|
1045
1171
|
(database migration)
|
1046
1172
|
```
|
@@ -1064,25 +1190,79 @@ enum status: {
|
|
1064
1190
|
}
|
1065
1191
|
```
|
1066
1192
|
|
1067
|
-
To set the labels, use
|
1193
|
+
To set the labels, use a class-level method that is a hash of keys-to-labels using a method named the same name as the enum method but with `_labels`
|
1068
1194
|
|
1069
1195
|
If no `_labels` method exists, Hot Glue will fallback to using the Postgres-defined names.
|
1070
1196
|
```
|
1071
1197
|
def self.status_labels
|
1072
1198
|
{
|
1073
|
-
pending: 'Is
|
1074
|
-
active: 'Is active',
|
1075
|
-
archived: 'Is
|
1199
|
+
pending: 'Is currently pending',
|
1200
|
+
active: 'Is really active',
|
1201
|
+
archived: 'Is done & archived',
|
1076
1202
|
disabled: 'Is Disabled',
|
1077
1203
|
waiting: 'Is Waiting'
|
1078
1204
|
}
|
1079
1205
|
```
|
1080
1206
|
|
1081
|
-
Now, your labels will show up as defined in the `_labels` ("Is
|
1207
|
+
Now, your labels will show up on the front-end as defined in the `_labels` ("Is currently pending", etc) instead of the database-values.
|
1082
1208
|
|
1083
1209
|
|
1084
1210
|
# VERSION HISTORY
|
1085
1211
|
|
1212
|
+
#### 2023-03-17 - v0.5.9
|
1213
|
+
- Attachments! You can use Hot Glue to seamlessly create an image, file, or video attachment. Please see the docs in new flag `--atachments` under the "Special Features" section
|
1214
|
+
|
1215
|
+
- Watch the demo on attachments here on YouTube: https://youtu.be/yJbjwReCr18
|
1216
|
+
|
1217
|
+
- Fixes to downnesting
|
1218
|
+
|
1219
|
+
- `--stacked-downnesting` flag — The Layout Builder now can stack downnesting portals instead of putting them side-by-side. When stacked, there is no limit to how many you can have and the entire stack takes up 4-bootstrap columns.
|
1220
|
+
|
1221
|
+
- Hot Glue has been moved on Github from my personal organization to a new organization named `hot-glue-for-rails`. The new Github url is: `https://github.com/hot-glue-for-rails/hot-glue`
|
1222
|
+
|
1223
|
+
|
1224
|
+
#### 2023-03-01 - v0.5.8
|
1225
|
+
|
1226
|
+
• Fixes spec assertions for enums to work with the enum `_label` field (when provided).
|
1227
|
+
|
1228
|
+
• Fixes `--form-label-position` (before/after) so that a carriage return is placed between the label & field correctly for either choice
|
1229
|
+
|
1230
|
+
• All spec files are now created in `spec/features/` folder (previously was `spec/system/` with `type: :feature`; they no longer have `type: :feature` as this is not necessary when they are in the `spec/features` folder)
|
1231
|
+
|
1232
|
+
• Corrects the hawk scope to only add the plural related entity when NOT using the shorthand `{ ... }`
|
1233
|
+
|
1234
|
+
• BEM (block element modifier)-style has been added list headings, show cells, edit cells. These class names will get added to the `<div>` tags for both the heading and cells.
|
1235
|
+
|
1236
|
+
The format is as follows:
|
1237
|
+
|
1238
|
+
For headings
|
1239
|
+
`heading--{singular}--{field name}-{field name}-{field name}`
|
1240
|
+
|
1241
|
+
For cells:
|
1242
|
+
`cell--{singular}--{field name}-{field name}-{field name}`
|
1243
|
+
use this to globally style different fields by object & field name
|
1244
|
+
|
1245
|
+
Note that if you have multiple fields inside one cell (for example, with specified grouping or smart layout), your fields names get concatenated using single-hyphens:
|
1246
|
+
For example, consider a customer scaffold with a first name & last name appearing in one cell. The cell itself will have a class of:
|
1247
|
+
`cell--customer--first_name-last_name`
|
1248
|
+
|
1249
|
+
If your cell contains only one field, for example, a phone number, it would look like this:
|
1250
|
+
`cell--customer--phone_number`
|
1251
|
+
|
1252
|
+
Tip: Use the _ends with_ and _starts with_ selectors, which can be used like this:.
|
1253
|
+
|
1254
|
+
```
|
1255
|
+
div[class$="--phone_number"] {
|
1256
|
+
text-decoration: underline;
|
1257
|
+
}
|
1258
|
+
```
|
1259
|
+
|
1260
|
+
|
1261
|
+
```
|
1262
|
+
|
1263
|
+
```
|
1264
|
+
|
1265
|
+
|
1086
1266
|
#### 2023-02-13 - v0.5.7 - factory-creation, alt lookups, update show only, fixes to Enums, support for Ruby 3.2
|
1087
1267
|
• See `--factory-creation` section.
|
1088
1268
|
|
@@ -1147,8 +1327,8 @@ License check has been removed (Hot Glue is now free to use for hobbyists and in
|
|
1147
1327
|
#### 2022-03-23 - v0.5.2 - Hawked Foreign Keys
|
1148
1328
|
|
1149
1329
|
- You can now protect your foreign keys from malicious input and also restrict the scope of drop downs to show only records with the specified access control restriction.
|
1150
|
-
- [Example #3](https://
|
1151
|
-
- [Example #4](https://
|
1330
|
+
- [Example #3](https://school.jasonfleetwoodboldt.com/8188) in the Hot Glue Tutorial shows you how to use the hawk to limit the scope to the logged in user.
|
1331
|
+
- [Example #4](https://school.jasonfleetwoodboldt.com/8188) in the Hot Glue Tutorial shows how to hawk to a non-usual scope, the inverse of the current user's belongs_to (that is, hawk the scope to X where current_user `belongs_to :x`)
|
1152
1332
|
|
1153
1333
|
|
1154
1334
|
#### 2022-03-12 - v0.5.1 - Inline List Labels
|