hot-glue 0.5.8 → 0.5.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -2
- data/Gemfile +1 -1
- data/README.md +267 -149
- data/app/helpers/hot_glue/controller_helper.rb +9 -6
- data/config/hot_glue.yml +2 -0
- data/lib/generators/hot_glue/direct_upload_install_generator.rb +48 -0
- data/lib/generators/hot_glue/dropzone_install_generator.rb +42 -0
- data/lib/generators/hot_glue/field_factory.rb +57 -0
- data/lib/generators/hot_glue/fields/association_field.rb +76 -0
- data/lib/generators/hot_glue/fields/attachment_field.rb +9 -0
- data/lib/generators/hot_glue/fields/boolean_field.rb +18 -0
- data/lib/generators/hot_glue/fields/date_field.rb +10 -0
- data/lib/generators/hot_glue/fields/date_time_field.rb +23 -0
- data/lib/generators/hot_glue/fields/enum_field.rb +27 -0
- data/lib/generators/hot_glue/fields/field.rb +51 -0
- data/lib/generators/hot_glue/fields/float_field.rb +11 -0
- data/lib/generators/hot_glue/fields/integer_field.rb +26 -0
- data/lib/generators/hot_glue/fields/string_field.rb +33 -0
- data/lib/generators/hot_glue/fields/text_field.rb +14 -0
- data/lib/generators/hot_glue/fields/time_field.rb +6 -0
- data/lib/generators/hot_glue/fields/uuid_field.rb +12 -0
- data/lib/generators/hot_glue/layout/builder.rb +15 -6
- data/lib/generators/hot_glue/layout_strategy/base.rb +2 -0
- data/lib/generators/hot_glue/layout_strategy/bootstrap.rb +4 -0
- data/lib/generators/hot_glue/markup_templates/erb.rb +158 -117
- data/lib/generators/hot_glue/scaffold_generator.rb +296 -306
- data/lib/generators/hot_glue/templates/computer_code.jpg +0 -0
- data/lib/generators/hot_glue/templates/controller.rb.erb +15 -9
- 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 +32 -111
- data/lib/hotglue/version.rb +1 -1
- data/script/clean_generated_code +1 -1
- metadata +22 -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.
|
@@ -41,8 +41,6 @@ Other than the opinionated differences and additional features, Hot Glue produce
|
|
41
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://school.jasonfleetwoodboldt.com/8188?utm_source=github.com&utm_campaign=github_hot_glue_readme_page)
|
45
|
-
|
46
44
|
---
|
47
45
|
---
|
48
46
|
## HOW EASY?
|
@@ -58,110 +56,65 @@ Instantly get a simple CRUD interface
|
|
58
56
|
|
59
57
|
![hot-glue-4](https://user-images.githubusercontent.com/59002/116405517-c2b2e300-a7fd-11eb-8423-d43e3afc9fa6.gif)
|
60
58
|
|
61
|
-
|
59
|
+
|
60
|
+
# Getting Started Video
|
61
|
+
[Hot Glue Getting Started (JSBundling)](https://www.youtube.com/watch?v=bzpXOhBkiDk)
|
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.
|
65
79
|
|
66
|
-
|
80
|
+
Section #4 is optional but highly recommended.
|
67
81
|
|
68
|
-
|
82
|
+
Section #5 is where you will pick a CSS Framework (Bootstrap, Tailwind, or none)
|
69
83
|
|
70
|
-
|
84
|
+
Section #6 is for two support gems (Kaminari) for Hot Glue
|
71
85
|
|
72
|
-
|
86
|
+
Section #7 is for Hot Glue itself
|
87
|
+
|
88
|
+
You will also need section #8 to setup Devise if you want authentication.
|
89
|
+
|
90
|
+
|
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
|
|
@@ -598,11 +535,11 @@ This is covered in [Example #4 in the Hot Glue Tutorial](https://school.jasonfle
|
|
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
|
|
@@ -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,33 +908,178 @@ Omits the heading of column names that appears above the 1st row of data.
|
|
956
908
|
|
957
909
|
## Special Features
|
958
910
|
|
959
|
-
### `--
|
911
|
+
### `--attachments`
|
960
912
|
|
961
|
-
|
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`)
|
962
918
|
|
963
|
-
Example:
|
964
919
|
```
|
965
|
-
|
920
|
+
bundle add image_processing
|
921
|
+
./bin/rails active_storage:install
|
922
|
+
./bin/rails db:migrate
|
966
923
|
```
|
967
924
|
|
968
|
-
|
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.
|
969
1065
|
|
970
|
-
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).
|
971
1066
|
|
972
|
-
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.)
|
973
1067
|
|
974
1068
|
|
975
1069
|
### `--factory-creation={ ... }`
|
976
1070
|
|
977
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.
|
978
1072
|
|
1073
|
+
You may use semi-colons to separate multiple lines of code.
|
1074
|
+
|
979
1075
|
For example, a user Factory might be called like so:
|
980
1076
|
|
981
|
-
|
1077
|
+
`./bin/rails generate hot_glue:scaffold User --factory-creation={factory = UserFactory.new(params: user_params)} --gd`
|
982
1078
|
|
983
1079
|
(Note we are relying on the `user_params` method provided by the controller.)
|
984
1080
|
|
985
1081
|
You must do one of two things:
|
1082
|
+
|
986
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.)
|
987
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
|
988
1085
|
|
@@ -1029,14 +1126,13 @@ agent_factory = AgentFactory.new(find_or_create_by_email: agent_company_params[:
|
|
1029
1126
|
|
1030
1127
|
|
1031
1128
|
|
1032
|
-
|
1033
|
-
|
1034
1129
|
## Automatic Base Controller
|
1035
1130
|
|
1036
1131
|
HotGlue will copy a file named base_controller.rb to the same folder where it tries to create any controller, unless such a file exists there already.
|
1037
1132
|
|
1038
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.
|
1039
1134
|
|
1135
|
+
|
1040
1136
|
## Special Table Labels
|
1041
1137
|
|
1042
1138
|
If your object is very wordy (like MyGreatHook) and you want it to display in the UI as something shorter,
|
@@ -1070,6 +1166,7 @@ Child portals have the headings omitted automatically (there is a heading identi
|
|
1070
1166
|
# Note about enums
|
1071
1167
|
|
1072
1168
|
The Rails 7 enum implementation for Postgres is very slick but has a counter-intuitive facet.
|
1169
|
+
|
1073
1170
|
Define your Enums in Postgres as strings:
|
1074
1171
|
(database migration)
|
1075
1172
|
```
|
@@ -1093,24 +1190,45 @@ enum status: {
|
|
1093
1190
|
}
|
1094
1191
|
```
|
1095
1192
|
|
1096
|
-
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`
|
1097
1194
|
|
1098
1195
|
If no `_labels` method exists, Hot Glue will fallback to using the Postgres-defined names.
|
1099
1196
|
```
|
1100
1197
|
def self.status_labels
|
1101
1198
|
{
|
1102
|
-
pending: 'Is
|
1103
|
-
active: 'Is active',
|
1104
|
-
archived: 'Is
|
1199
|
+
pending: 'Is currently pending',
|
1200
|
+
active: 'Is really active',
|
1201
|
+
archived: 'Is done & archived',
|
1105
1202
|
disabled: 'Is Disabled',
|
1106
1203
|
waiting: 'Is Waiting'
|
1107
1204
|
}
|
1108
1205
|
```
|
1109
1206
|
|
1110
|
-
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.
|
1111
1208
|
|
1112
1209
|
|
1113
1210
|
# VERSION HISTORY
|
1211
|
+
#### 2023-04-08 - v0.5.9.2
|
1212
|
+
• This begins a refactor of the field knowledge into properly abstracted Field objects
|
1213
|
+
• No functional changes, except that the specs now contain an `attach_file` for attachments.
|
1214
|
+
|
1215
|
+
#### - v0.5.9.1
|
1216
|
+
• Fixed issue with ownership fields coming through as associations.
|
1217
|
+
|
1218
|
+
|
1219
|
+
|
1220
|
+
#### 2023-03-17 - v0.5.9
|
1221
|
+
- 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
|
1222
|
+
|
1223
|
+
- Watch the demo on attachments here on YouTube: https://youtu.be/yJbjwReCr18
|
1224
|
+
|
1225
|
+
- Fixes to downnesting
|
1226
|
+
|
1227
|
+
- `--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.
|
1228
|
+
|
1229
|
+
- 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`
|
1230
|
+
|
1231
|
+
|
1114
1232
|
#### 2023-03-01 - v0.5.8
|
1115
1233
|
|
1116
1234
|
• Fixes spec assertions for enums to work with the enum `_label` field (when provided).
|
@@ -1132,7 +1250,7 @@ For cells:
|
|
1132
1250
|
`cell--{singular}--{field name}-{field name}-{field name}`
|
1133
1251
|
use this to globally style different fields by object & field name
|
1134
1252
|
|
1135
|
-
Note that if you have multiple fields inside one cell (for example, with specified grouping or smart layout), your fields names get
|
1253
|
+
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:
|
1136
1254
|
For example, consider a customer scaffold with a first name & last name appearing in one cell. The cell itself will have a class of:
|
1137
1255
|
`cell--customer--first_name-last_name`
|
1138
1256
|
|