hot-glue 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +0 -1
- data/README.md +135 -42
- data/lib/generators/hot_glue/scaffold_generator.rb +25 -2
- data/lib/generators/hot_glue/templates/controller.rb.erb +11 -40
- data/lib/generators/hot_glue/templates/erb/_line.erb +2 -2
- data/lib/generators/hot_glue/templates/erb/_list.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/_new_button.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/_new_form.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/create.turbo_stream.erb +2 -2
- data/lib/generators/hot_glue/templates/erb/destroy.turbo_stream.erb +2 -2
- data/lib/generators/hot_glue/templates/erb/edit.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/edit.turbo_stream.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/update.turbo_stream.erb +1 -1
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +3 -1
- data/lib/hotglue/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4770a6dafa96c7d17e2104d7349caf126a7922c660b3055b29c6a7eab6e7d851
|
4
|
+
data.tar.gz: cd730bb99e9d9dad8ca5ee22a504a9e91ace01123ce900e11c7ccffae3e26630
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f59544515a51f85e494bd7a1ec7ee4586ab761919554f53ad751b845906e412a5cd80f65e1447183d79246e295abbb1fe468814ef572cd93888970603aafb7a
|
7
|
+
data.tar.gz: 045115777e9399ddffd06f9b400d44cc1d5e230579ea9d2017213cf74ae786efe2ae42d52639dbc60b496d0628f8a955c0d03807cd7262203de1961e0ecf87c8
|
data/.github/workflows/test.yml
CHANGED
data/README.md
CHANGED
@@ -5,9 +5,7 @@ Hot Glue is a Rails scaffold builder for the Turbo era. It is an evolution of th
|
|
5
5
|
|
6
6
|
Using Turbo-Rails and Hotwire (default in Rails 7) you get a lightning-fast out-of-the-box CRUD-building experience.
|
7
7
|
|
8
|
-
Every page displays only a list view: new and edit operations happen as 'edit-in-place,' so the user never leaves the page.
|
9
|
-
|
10
|
-
Because all page navigation is Turbo's responsibility, everything plugs & plays nicely into a Turbo-backed Rails app.
|
8
|
+
Every page displays only a list view: new and edit operations happen as 'edit-in-place,' so the user never leaves the page. Because all page navigation is Turbo's responsibility, everything plugs & plays nicely into a Turbo-backed Rails app.
|
11
9
|
|
12
10
|
Alternatively, you can use this tool to create a Turbo-backed *section* of your Rails app -- such as an admin interface -- while still treating the rest of the Rails app as an API or building out other features by hand.
|
13
11
|
|
@@ -27,6 +25,16 @@ Hot Glue generates functionality that is quick and dirty. It lets you be crafty.
|
|
27
25
|
* Nest your routes model-by-model for built-in poor man's authentication.
|
28
26
|
* Throw the scaffolding away when your app is ready to graduate to its next phase.
|
29
27
|
|
28
|
+
How is it different than Rails scaffolding?
|
29
|
+
|
30
|
+
Although inspired by the Rails scaffold generators (built-in to Rails), Hot Glue does something similiar but has made opinionated decisions that deviate from the normal Rails scaffold:
|
31
|
+
|
32
|
+
1. The Hot Glue scaffolds are complete packages and pre-optimized for 'edit-in-place.' (the Rails scaffolds still generate views that make you flip between pages to do create/update operations)
|
33
|
+
2. Hot Glue does not create your models along with your scaffolding. Instead, create them first using `rails model new`
|
34
|
+
3. Hot Glue *reads* the fields on your database and the relationships defined on your models, so unlike the Rails scaffolding you must do that step before building your scaffolding.
|
35
|
+
4. Hot Glue has many more features for building layouts quickly, like choosing which fields to include or exclude and how to lay them out on the page, for stiching together related objects (nesting and child portals), and more.
|
36
|
+
|
37
|
+
Other than the opinionated differences and additional features, Hot Glue produces code that is fundamentally very similiar and works consistent with the Rails 7 ways of working.
|
30
38
|
|
31
39
|
# Get Hot Glue
|
32
40
|
|
@@ -36,16 +44,6 @@ Hot Glue generates functionality that is quick and dirty. It lets you be crafty.
|
|
36
44
|
[![Hot Glue Course](https://user-images.githubusercontent.com/59002/189544503-6edbcd40-1728-4b13-ac9a-c7772ccb8284.jpg)](https://jfbcodes.com/courses/hot-glue-in-depth-tutorial/?utm_source=github.com&utm_campaign=github_hot_glue_readme_page)
|
37
45
|
|
38
46
|
---
|
39
|
-
|
40
|
-
|
41
|
-
## GETTING STARTED VIDEO
|
42
|
-
|
43
|
-
|
44
|
-
~~Check it out on Youtube at https://www.youtube.com/watch?v=bKjKHMTvzZc~~
|
45
|
-
|
46
|
-
While you're over there could you give my Youtube channel a 'Subscribe'? (look for the RED SUBSCRIBE BUTTON)
|
47
|
-
|
48
|
-
|
49
47
|
---
|
50
48
|
## HOW EASY?
|
51
49
|
|
@@ -71,29 +69,101 @@ To run Turbo (which Hot Glue requires), you must either (1) be running an Import
|
|
71
69
|
|
72
70
|
For reference, see https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-do-i-need-importmap-rails/
|
73
71
|
|
72
|
+
Once you create the new Rails app, you can skip to the 'Super-Quick Setup' below.
|
73
|
+
|
74
74
|
(1) To use ImportMap Rails, start with
|
75
75
|
`rails new`
|
76
76
|
|
77
|
-
|
77
|
+
(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
78
|
|
79
79
|
(2) To use JSBundling, start with
|
80
80
|
`rails new --javascript=jsbundling`
|
81
81
|
|
82
82
|
|
83
83
|
**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
|
-
If you want Bootstrap, install it following these instructions
|
84
|
+
(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
|
+
|
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/)
|
87
|
+
|
88
|
+
(For the old method of installing Bootstrap [see this post](https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-bootstrap/))
|
89
|
+
|
90
|
+
(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
|
+
|
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
|
85
95
|
|
86
|
-
|
87
|
-
`rails new --skip-javascript`
|
96
|
+
Be sure to do `git add .` and `git commit -m "initial commit"` after creating your new Rails 7 app.
|
88
97
|
|
89
|
-
|
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
|
+
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
|
+
```
|
90
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
|
+
```
|
91
162
|
|
92
|
-
For the old method of installing Bootstrap [see this post](https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-bootstrap/)
|
93
163
|
|
94
|
-
|
164
|
+
## Step-By-Step Setup
|
95
165
|
|
96
|
-
|
166
|
+
### 2. ADD RSPEC, FACTORY-BOT, AND FFAKER
|
97
167
|
|
98
168
|
add these 3 gems to your gemfile **inside a group for both :development and :test*.
|
99
169
|
Do not add these gems to *only* the :test group or else your Rspec installer and generators will not work correctly.
|
@@ -105,19 +175,19 @@ group :development, :test do
|
|
105
175
|
end
|
106
176
|
```
|
107
177
|
|
108
|
-
|
178
|
+
#### Rspec Installer
|
109
179
|
- run `rails generate rspec:install`
|
110
180
|
|
111
181
|
- Because you are not using Minitest, you can delete the `test/` folder at the root of your repository.
|
112
182
|
|
113
183
|
|
114
184
|
|
115
|
-
|
185
|
+
### 3. HOTGLUE INSTALLER
|
116
186
|
Add `gem 'hot-glue'` to your Gemfile & `bundle install`
|
117
187
|
|
118
188
|
During in installation, you MUST supply a `--layout` flag.
|
119
189
|
|
120
|
-
|
190
|
+
#### `--layout` flag (only two options: `hotglue` or `bootstrap`; default is `bootstrap`)
|
121
191
|
Here you will set up and install Hot Glue for the first time.
|
122
192
|
|
123
193
|
It will install a config file that will save two preferences: layout (`hotglue` or `bootstrap`)
|
@@ -125,7 +195,7 @@ It will install a config file that will save two preferences: layout (`hotglue`
|
|
125
195
|
The installer will create `config/hot_glue.yml`.
|
126
196
|
|
127
197
|
|
128
|
-
|
198
|
+
#### `--theme` flag
|
129
199
|
During the installation, **if** your `--layout` flag is set to `hotglue` you must also pass `--theme` flag.
|
130
200
|
|
131
201
|
the themes are:
|
@@ -136,21 +206,21 @@ the themes are:
|
|
136
206
|
• like_cupertino (modern Apple-UX inspired)
|
137
207
|
|
138
208
|
|
139
|
-
|
209
|
+
#### `--markup` flag (NOTE: haml and slim are no longer supported at this time)
|
140
210
|
|
141
211
|
default is `erb`. IMPORTANT: As of right now, HAML and SLIM are not currently supported so the only option is also the default `erb`.
|
142
212
|
|
143
213
|
|
144
|
-
|
214
|
+
#### example installing ERB using Bootstrap layout:
|
145
215
|
`rails generate hot_glue:install --markup=erb --layout=bootstrap`
|
146
216
|
|
147
|
-
|
217
|
+
#### Example installing using Hot Glue layout and the 'like_mountain_view' (Gmail-inspired) theme:
|
148
218
|
`rails generate hot_glue:install --markup=erb --layout=hotglue --theme=like_mountain_view`
|
149
219
|
|
150
220
|
The Hot Glue installer did several things for you in this step. Examine the git diffs or see 'Hot Glue Installer Notes' below.
|
151
221
|
|
152
222
|
|
153
|
-
|
223
|
+
### 4. Font-awesome (optional)
|
154
224
|
|
155
225
|
I recommend
|
156
226
|
https://github.com/tomkra/font_awesome5_rails
|
@@ -158,7 +228,7 @@ or
|
|
158
228
|
https://github.com/FortAwesome/font-awesome-sass
|
159
229
|
|
160
230
|
|
161
|
-
|
231
|
+
### 5. Devise
|
162
232
|
(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)
|
163
233
|
https://github.com/jasonfb/hot-glue/blob/main/README2.md
|
164
234
|
|
@@ -203,11 +273,11 @@ Add the data-turbo false option in the html key of the form, shown in bold here:
|
|
203
273
|
form_for(resource, as: resource_name, **html: {'data-turbo' => "false"},** url: session_path(resource_name) ) do |f|
|
204
274
|
|
205
275
|
|
206
|
-
|
276
|
+
#### Hot Glue Installer Notes
|
207
277
|
|
208
278
|
These things were **done for you** in Step #3 (above). You don't need to think about them but if you are familiar with Capybara and/or adding Hot Glue to an existing app, you may want to:
|
209
279
|
|
210
|
-
|
280
|
+
##### Hot Glue modified `application.html.erb`
|
211
281
|
Note: if you have some kind of non-standard application layout, like one at a different file
|
212
282
|
or if you have modified your opening <body> tag, this may not have been automatically applied by the installer.
|
213
283
|
|
@@ -216,7 +286,7 @@ or if you have modified your opening <body> tag, this may not have been automati
|
|
216
286
|
<%= render partial: 'layouts/flash_notices' %>
|
217
287
|
```
|
218
288
|
|
219
|
-
|
289
|
+
##### Hot Glue modified `rails_helper.rb`
|
220
290
|
Note: if you have some kind of non-standard rails_helper.rb, like one that does not use the standard ` do |config|` syntax after your `RSpec.configure`
|
221
291
|
this may not have been automatically applied by the installer.
|
222
292
|
|
@@ -229,7 +299,7 @@ this may not have been automatically applied by the installer.
|
|
229
299
|
```
|
230
300
|
|
231
301
|
|
232
|
-
|
302
|
+
##### Hot Glue switched Capybara from RACK-TEST to HEADLESS CHROME
|
233
303
|
|
234
304
|
- By default Capybara is installed with :rack_test as its driver.
|
235
305
|
- This does not support Javascript. Hot Glue is not targeted for fallback browsers.
|
@@ -269,7 +339,7 @@ Alternatively, you can define your own driver like so:
|
|
269
339
|
|
270
340
|
```
|
271
341
|
|
272
|
-
|
342
|
+
##### Hot Glue Added a Quick (Old-School) Capybara Login For Devise
|
273
343
|
|
274
344
|
- for a quick Capybara login, create a support helper in `spec/support/` and log-in as your user
|
275
345
|
- in the default code, the devise login would be for an object called account and lives at the route `/accounts/sign_in`
|
@@ -287,7 +357,7 @@ Alternatively, you can define your own driver like so:
|
|
287
357
|
|
288
358
|
---
|
289
359
|
---
|
290
|
-
|
360
|
+
---
|
291
361
|
|
292
362
|
# HOT GLUE DOCS
|
293
363
|
|
@@ -296,6 +366,9 @@ Alternatively, you can define your own driver like so:
|
|
296
366
|
|
297
367
|
TitleCase class name of the thing you want to build a scaffoling for.
|
298
368
|
|
369
|
+
rails generate hot_glue:scaffold Thing
|
370
|
+
|
371
|
+
(note: Your Thing object must belong_to an authenticated User or alternatively you must create a Gd controller, see below.)
|
299
372
|
|
300
373
|
## Options With Arguments
|
301
374
|
|
@@ -520,14 +593,12 @@ An better alternative is to define the non-standard plurlizations globally in yo
|
|
520
593
|
Make a file at `config/initializers/inflections.rb`
|
521
594
|
|
522
595
|
# Add new inflection rules using the following format
|
596
|
+
```
|
523
597
|
ActiveSupport::Inflector.inflections do |inflect|
|
524
598
|
inflect.irregular 'clothing', 'clothes'
|
525
599
|
inflect.irregular 'human', 'humans'
|
526
|
-
|
527
|
-
|
528
|
-
# the standard pluralization is pretty sexist and will pluralize `human` to `humen`
|
529
600
|
end
|
530
|
-
|
601
|
+
```
|
531
602
|
|
532
603
|
### `--form-labels-position` (default: `after`; options are **before**, **after**, and **omit**)
|
533
604
|
By default form labels appear after the form inputs. To make them appear before or omit them, use this flag.
|
@@ -546,8 +617,6 @@ If you specify any exclude list, those excluded **and** the default exclude list
|
|
546
617
|
|
547
618
|
`rails generate hot_glue:scaffold Account --exclude=password`
|
548
619
|
|
549
|
-
(The default excluded list is: If you want to edit any fields with the same name, you must use the include flag instead.)
|
550
|
-
|
551
620
|
|
552
621
|
### `--include=`
|
553
622
|
Separate field names by COMMA
|
@@ -784,8 +853,19 @@ Sometimes you might want to redisplay the entire list after you make an update (
|
|
784
853
|
|
785
854
|
To do this, use flag `--display-list-after-update`. The update will behave like delete and re-fetch all the records in the result and tell Turbo to swap out the entire list.
|
786
855
|
|
856
|
+
### `--with-turbo-streams`
|
857
|
+
|
858
|
+
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` (wether 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.
|
859
|
+
|
860
|
+
**_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.
|
787
861
|
|
862
|
+
This happens using two interconnected mechanisms:
|
788
863
|
|
864
|
+
1) by default, all Hot Glue scaffold is wrapped in `turbo_frame_tag`s. The id of these tags is your namespace + the Rails dom_id(...). That means all Hot Glue scaffold is namespaced to the namespaces you use and won't collide with other turbo_frame_tag you might be using elsewhere
|
865
|
+
|
866
|
+
2) by appending **model callbacks**, we can automatically broadcast updates to the users who are using the Hot Glue scaffold. The model callbacks (after_update_commit and after_destroy_commit) get appended automatically to the top of your model file. Each model callback targets the scaffold being built (so just this scaffold), using its namespace, and renders the line partial (or destroys the content in the case of delete) from the scaffolding.
|
867
|
+
|
868
|
+
please note that *creating* and *deleting* do not yet have a full & complete implementation: Your pages won't re-render the pages being viewed cross-peer (that is, between two users using the app at the same time) if the insertion or deletion causes the pagination to be off for another user.
|
789
869
|
|
790
870
|
|
791
871
|
## Automatic Base Controller
|
@@ -825,6 +905,19 @@ Child portals have the headings omitted automatically (there is a heading identi
|
|
825
905
|
|
826
906
|
# VERSION HISTORY
|
827
907
|
|
908
|
+
#### 2022-11-27 - v0.5.4 - new flag --with-turbo-streams will append callbacks after_update_commit and after_destroy_commit to the MODEL you are building with to use turbo to target the scaffolding being built and programmatically update it
|
909
|
+
|
910
|
+
Adds `--with-turbo-streams`. Use `--with-turbo-streams` to create hot (live reload) interfaces. See docs above.
|
911
|
+
|
912
|
+
|
913
|
+
#### 2022-11-24 - v0.5.3 - New testing paradigm & removes license requirements
|
914
|
+
|
915
|
+
New testing paradigm
|
916
|
+
Code cleanup
|
917
|
+
Testing on CircleCI
|
918
|
+
License check has been removed (Hot Glue is now free to use for hobbyists and individuals. Business licenses are still available at https://heliosdev.shop/hot-glue-license)
|
919
|
+
|
920
|
+
|
828
921
|
#### 2022-03-23 - v0.5.2 - Hawked Foreign Keys
|
829
922
|
|
830
923
|
- 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.
|
@@ -122,7 +122,8 @@ module HotGlue
|
|
122
122
|
class_option :smart_layout, type: :boolean, default: false
|
123
123
|
class_option :markup, type: :string, default: nil # deprecated -- use in app config instead
|
124
124
|
class_option :layout, type: :string, default: nil # if used here it will override what is in the config
|
125
|
-
class_option :hawk, type: :string, default: nil
|
125
|
+
class_option :hawk, type: :string, default: nil
|
126
|
+
class_option :with_turbo_streams, type: :boolean, default: false
|
126
127
|
|
127
128
|
class_option :no_list_label, type: :boolean, default: false
|
128
129
|
|
@@ -415,7 +416,7 @@ module HotGlue
|
|
415
416
|
|
416
417
|
@menu_file_exists = true if @nested_set.none? && File.exists?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
|
417
418
|
|
418
|
-
|
419
|
+
@turbo_streams = !!options['with_turbo_streams']
|
419
420
|
end
|
420
421
|
|
421
422
|
def setup_hawk_keys
|
@@ -940,6 +941,28 @@ module HotGlue
|
|
940
941
|
|
941
942
|
end
|
942
943
|
|
944
|
+
def append_model_callbacks
|
945
|
+
# somehow the generator invokes this
|
946
|
+
if options['with_turbo_streams'] == true
|
947
|
+
dest_filename = cc_filename_with_extensions("#{singular_class.underscore}", "rb")
|
948
|
+
dest_filepath = File.join("#{'dummy/' if Rails.env.test?}app/models", dest_filename)
|
949
|
+
|
950
|
+
|
951
|
+
puts "appending turbo callbacks to #{dest_filepath}"
|
952
|
+
|
953
|
+
text = File.read(dest_filepath)
|
954
|
+
|
955
|
+
append_text = "class #{singular_class} < ApplicationRecord\n"
|
956
|
+
if !text.include?("include ActionView::RecordIdentifier")
|
957
|
+
append_text << " include ActionView::RecordIdentifier\n"
|
958
|
+
end
|
959
|
+
append_text << " after_update_commit lambda { broadcast_replace_to self, target: \"#{@namespace}__\#{dom_id(self)}\", partial: \"#{@namespace}/#{@plural}/line\" }\n after_destroy_commit lambda { broadcast_remove_to self, target: \"#{@namespace}__\#{dom_id(self)}\"}\n"
|
960
|
+
|
961
|
+
replace = text.gsub(/class #{singular_class} < ApplicationRecord/, append_text)
|
962
|
+
File.open(dest_filepath, "w") {|file| file.puts replace}
|
963
|
+
end
|
964
|
+
end
|
965
|
+
|
943
966
|
def namespace_with_dash
|
944
967
|
if @namespace
|
945
968
|
"/#{@namespace}"
|
@@ -68,22 +68,13 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
68
68
|
|
69
69
|
def index
|
70
70
|
load_all_<%= plural %>
|
71
|
-
respond_to do |format|
|
72
|
-
format.html
|
73
|
-
end
|
74
71
|
end
|
75
72
|
|
76
|
-
<% if create_action %> def new
|
77
|
-
<%
|
78
|
-
@<%= singular_name %> = <%= class_name %>.new(<% if eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)
|
79
|
-
|
80
|
-
<% elsif @object_owner_optional && any_nested? %>
|
73
|
+
<% if create_action %> def new <% if @object_owner_sym %>
|
74
|
+
@<%= singular_name %> = <%= class_name %>.new(<% if eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>) <% elsif @object_owner_optional && any_nested? %>
|
81
75
|
@<%= singular_name %> = <%= class_name %>.new({}.merge(<%= @nested_set.last[:singular] %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {})) <% else %>
|
82
76
|
@<%= singular_name %> = <%= class_name %>.new(<% if any_nested? %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)
|
83
77
|
<% end %>
|
84
|
-
respond_to do |format|
|
85
|
-
format.html
|
86
|
-
end
|
87
78
|
end
|
88
79
|
|
89
80
|
def create
|
@@ -95,46 +86,30 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
95
86
|
if @<%= singular_name %>.save
|
96
87
|
flash[:notice] = "Successfully created #{@<%= singular %>.<%= display_class %>}"
|
97
88
|
load_all_<%= plural %>
|
98
|
-
|
99
|
-
format.turbo_stream
|
100
|
-
format.html { redirect_to <%= path_helper_plural %> }
|
101
|
-
end
|
89
|
+
render :create
|
102
90
|
else
|
103
91
|
flash[:alert] = "Oops, your <%= singular_name %> could not be created. #{@hawk_alarm}"
|
104
|
-
|
105
|
-
format.turbo_stream
|
106
|
-
format.html
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
<% end %> def show
|
112
|
-
respond_to do |format|
|
113
|
-
format.html
|
92
|
+
render :create, status: :unprocessable_entity
|
114
93
|
end
|
115
94
|
end
|
116
95
|
|
96
|
+
<% end %>
|
117
97
|
<% unless @no_edit %> def edit
|
118
|
-
|
119
|
-
format.turbo_stream
|
120
|
-
format.html
|
121
|
-
end
|
98
|
+
render :edit
|
122
99
|
end
|
123
100
|
|
124
101
|
<% end %><% if @build_update_action %> def update
|
125
102
|
modified_params = modify_date_inputs_on_params(<%= singular %>_params<%= @auth ? ', ' + @auth : '' %>)<%= controller_update_params_tap_away_magic_buttons %><% if @hawk_keys.any? %>
|
126
103
|
modified_params = hawk_params( {<%= hawk_to_ruby %>}, modified_params)<% end %>
|
127
|
-
<%= controller_magic_button_update_actions %>
|
104
|
+
<%= controller_magic_button_update_actions %>
|
105
|
+
if @<%= singular_name %>.update(modified_params)
|
106
|
+
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
128
107
|
flash[:notice] = (flash[:notice] || "") << "Saved #{@<%= singular %>.<%= display_class %>}"
|
129
108
|
flash[:alert] = @hawk_alarm if @hawk_alarm
|
109
|
+
render :update
|
130
110
|
else
|
131
111
|
flash[:alert] = (flash[:alert] || "") << "<%= singular_name.titlecase %> could not be saved. #{@hawk_alarm}"
|
132
|
-
|
133
|
-
end
|
134
|
-
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
135
|
-
respond_to do |format|
|
136
|
-
format.turbo_stream
|
137
|
-
format.html
|
112
|
+
render :update, status: :unprocessable_entity
|
138
113
|
end
|
139
114
|
end
|
140
115
|
|
@@ -145,10 +120,6 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
145
120
|
flash[:alert] = "<%= singular_name.titlecase %> could not be deleted."
|
146
121
|
end
|
147
122
|
load_all_<%= plural %>
|
148
|
-
respond_to do |format|
|
149
|
-
format.turbo_stream
|
150
|
-
format.html { redirect_to <%= path_helper_plural %> }
|
151
|
-
end
|
152
123
|
end<% end %>
|
153
124
|
|
154
125
|
def <%=singular_name%>_params
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
<% if @turbo_streams %><\%= turbo_stream_from <%= singular %> %>
|
2
|
+
<% end %><\%= turbo_frame_tag "<%= @namespace %>__#{ dom_id(<%= singular %>) }" do %>
|
3
3
|
<div class='row scaffold-row' data-id='<\%= <%= singular %>.id %>' data-edit='false'>
|
4
4
|
<\%= render partial: '<%= show_path_partial %>', locals: { <%= singular %>: <%= singular %> }<% @nested_set.each do |nest_arg| %>.merge(defined?(<%= nest_arg[:singular] %>) ? {<%= nest_arg[:singular] %>: <%= nest_arg[:singular] %>, nested_for: "<%= nest_arg[:singular] %>-#{<%= nest_arg[:singular] %>.id}"} : {})<% end %> %>
|
5
5
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<\%= turbo_frame_tag "<%= plural %>-list" <%= nested_for_turbo_id_list_constructor %> do %>
|
1
|
+
<\%= turbo_frame_tag "<%= @namespace %>__<%= plural %>-list" <%= nested_for_turbo_id_list_constructor %> do %>
|
2
2
|
<div class="<%= @container_name %> scaffold-list">
|
3
3
|
<% unless @no_list || @no_list_label || (@nested_set.any? && !@nested_set.collect{|x| x[:optional]}.any?) %>
|
4
4
|
<% unless list_label.nil? %><h4>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<\%= turbo_frame_tag "<%= singular %>-new" do %>
|
1
|
+
<\%= turbo_frame_tag "<%= @namespace %>__<%= singular %>-new" do %>
|
2
2
|
<div>
|
3
3
|
<\%= link_to "New <%= thing_label %>", <%= new_path_name %>, disable_with: "Loading...", class: "new-<%= singular %>-button btn btn-primary pull-right <%= 'btn-sm' if @nested_set.any? %> " %>
|
4
4
|
</div>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<\% if @<%= singular %>.errors.none? %>
|
2
|
-
<\%= turbo_stream.replace "<%= plural %>-list" + <%= nested_for_turbo_nested_constructor %> do %>
|
2
|
+
<\%= turbo_stream.replace "<%= @namespace %>__<%= plural %>-list" + <%= nested_for_turbo_nested_constructor %> do %>
|
3
3
|
<\%= render partial: "list", locals: {<%= plural %>: @<%= plural %>}<%= @nested_set.collect{|arg| ".merge(@" + arg[:singular] + " ? {nested_for: \"" + arg[:singular] + "-\#{@" + arg[:singular] + ".id}\"" + ", " + arg[:singular] + ": @" + arg[:singular] + "} : {})"}.join() %> \%>
|
4
4
|
<\% end %>
|
5
5
|
<\% end %>
|
6
|
-
<\%= turbo_stream.replace "<%= singular %>-new" do %>
|
6
|
+
<\%= turbo_stream.replace "<%= @namespace %>__<%= singular %>__<%= singular %>-new" do %>
|
7
7
|
<\% if @<%= singular %>.errors.none? %>
|
8
8
|
<\%= render partial: "new_button", locals: {}<%= @nested_set.collect{|arg| ".merge(@" + arg[:singular] + " ? {" + arg[:singular] + ": @" + arg[:singular] + "} : {})"}.join() %> %>
|
9
9
|
<\% else %>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<\%= turbo_stream.replace "<%= plural %>-list" + <%= nested_for_turbo_nested_constructor %> do %>
|
1
|
+
<\%= turbo_stream.replace "<%= @namespace %>__<%= plural %>-list" + <%= nested_for_turbo_nested_constructor %> do %>
|
2
2
|
<\%= render partial: "list", locals: {<%=plural%>: @<%=plural%> }<%= @nested_set.collect{|arg| ".merge(@" + arg[:singular] + " ? {nested_for: \"" + arg[:singular] + "-\#{@" + arg[:singular] + ".id}\"" + ", " + arg[:singular] + ": @" + arg[:singular] + "} : {})"}.join() %> \%>
|
3
|
-
<\% end %>
|
3
|
+
<\% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<\%= link_to "<i class='fa fa-arrow-circle-left 2x'></i> Back to list".html_safe, <%= path_helper_plural %> %>
|
2
2
|
|
3
|
-
<\%= turbo_frame_tag "<%=
|
3
|
+
<\%= turbo_frame_tag "<%= @namespace %>__#{dom_id(@<%= singular %>)}" do %>
|
4
4
|
|
5
5
|
<div class="cell editable" style="position: relative;">
|
6
6
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<% if !@display_list_after_update %><\%= turbo_stream.replace "<%=
|
1
|
+
<% if !@display_list_after_update %><\%= turbo_stream.replace "<%= namespace %>__#{dom_id(@<%= singular %>)}" do %>
|
2
2
|
<\%= render partial: 'line', locals: {<%= singular %>: @<%= singular %> }<%= @nested_set.collect{|arg| ".merge(@#{arg[:singular]} ? {#{arg[:singular]}: @#{arg[:singular]}} : {})" }.join %> \%>
|
3
3
|
<\% end %><% else %><\%= turbo_stream.replace "<%= plural %>-list" do %>
|
4
4
|
<\%= render partial: '<%= list_path_partial %>', locals: {<%= plural %>: @<%= plural %>}<%= @nested_set.collect{|arg| ".merge(@#{arg[:singular]} ? {#{arg[:singular]}: @#{arg[:singular]}} : {})" }.join %> \%>
|
@@ -2,6 +2,8 @@ require 'rails_helper'
|
|
2
2
|
|
3
3
|
describe "interaction for <%= controller_class_name %>", type: :feature do
|
4
4
|
include HotGlue::ControllerHelper
|
5
|
+
include ActionView::RecordIdentifier
|
6
|
+
|
5
7
|
<%= @existing_content %>
|
6
8
|
<% unless @god %>let(:<%= @auth %>) {create(:<%= @auth.gsub('current_', '') %>)}<%end%>
|
7
9
|
<%= (@columns - @show_only).map { |col|
|
@@ -118,7 +120,7 @@ describe "interaction for <%= controller_class_name %>", type: :feature do
|
|
118
120
|
expect(page).to have_content("Editing #{<%= singular %>1.<%= @display_class %>.squish || "(no name)"}")
|
119
121
|
<%= test_capybara_block %>
|
120
122
|
click_button "Save"
|
121
|
-
within("turbo-frame#<%=
|
123
|
+
within("turbo-frame#<%= @namespace %>__#{dom_id(<%= singular %>1)} ") do
|
122
124
|
<%=
|
123
125
|
(@columns - @show_only).map { |col|
|
124
126
|
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
data/lib/hotglue/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hot-glue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Fleetwood-Boldt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|