hot-glue 0.2.6 → 0.2.9E
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/Gemfile.lock +1 -21
- data/README.md +155 -99
- data/lib/generators/hot_glue/markup_templates/erb.rb +19 -2
- data/lib/generators/hot_glue/markup_templates/haml.rb +2 -2
- data/lib/generators/hot_glue/scaffold_generator.rb +84 -34
- data/lib/generators/hot_glue/templates/controller.rb.erb +16 -22
- data/lib/generators/hot_glue/templates/erb/_line.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/_list.erb +10 -2
- data/lib/generators/hot_glue/templates/erb/_show.erb +18 -2
- data/lib/generators/hot_glue/templates/erb/create.turbo_stream.erb +3 -3
- data/lib/generators/hot_glue/templates/erb/destroy.turbo_stream.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/edit.erb +2 -5
- data/lib/generators/hot_glue/templates/erb/index.erb +1 -2
- data/lib/generators/hot_glue/templates/erb/update.turbo_stream.erb +5 -2
- data/lib/generators/hot_glue/templates/haml/_line.haml +1 -1
- data/lib/generators/hot_glue/templates/haml/_list.haml +5 -1
- data/lib/generators/hot_glue/templates/haml/create.turbo_stream.haml +3 -3
- data/lib/generators/hot_glue/templates/haml/destroy.turbo_stream.haml +1 -1
- data/lib/generators/hot_glue/templates/haml/edit.haml +0 -2
- data/lib/generators/hot_glue/templates/haml/index.haml +1 -2
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +19 -8
- data/lib/hot-glue.rb +1 -2
- data/lib/hotglue/version.rb +1 -1
- metadata +19 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 694eeeb9fd33b795d9f231788f078b48de4417ab38d5bd8194da97e214d0eb49
|
4
|
+
data.tar.gz: 1cea85144279962b16695b36b22d7e523333343e361a4240932ef34dd8468a80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26fcba271d8af01f7eac6a86597eab276991ea9a4510f3f1f41cec0898e9a8162f82c76993d090e3383f037951eb495b0f577feb44900d7342552ffba616fd1d
|
7
|
+
data.tar.gz: c286a2b3ce6dd43b598ffec01266c963420cbacf2af68abc3609cd99169ba4fc0eca3944cd8dc4c55af90691f2a572a9d1113c61a50c00ff5b54ae6ba53d201f
|
data/.github/FUNDING.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
github: [jasonfb]
|
2
|
-
custom: ["https://
|
2
|
+
custom: ["https://heliosdev.shop?utm_source=gh_hot_glue_funding_link"]
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hot-glue (0.2.
|
4
|
+
hot-glue (0.2.7)
|
5
5
|
ffaker (~> 2.16)
|
6
|
-
haml-rails (~> 2.0)
|
7
6
|
kaminari (~> 1.2)
|
8
7
|
rails (> 5.1, <= 7.0.0)
|
9
8
|
sass-rails
|
@@ -90,25 +89,10 @@ GEM
|
|
90
89
|
warden (~> 1.2.3)
|
91
90
|
diff-lcs (1.4.4)
|
92
91
|
erubi (1.10.0)
|
93
|
-
erubis (2.7.0)
|
94
92
|
ffaker (2.20.0)
|
95
93
|
ffi (1.15.4)
|
96
94
|
globalid (0.4.2)
|
97
95
|
activesupport (>= 4.2.0)
|
98
|
-
haml (5.2.2)
|
99
|
-
temple (>= 0.8.0)
|
100
|
-
tilt
|
101
|
-
haml-rails (2.0.1)
|
102
|
-
actionpack (>= 5.1)
|
103
|
-
activesupport (>= 5.1)
|
104
|
-
haml (>= 4.0.6, < 6.0)
|
105
|
-
html2haml (>= 1.0.1)
|
106
|
-
railties (>= 5.1)
|
107
|
-
html2haml (2.2.0)
|
108
|
-
erubis (~> 2.7.0)
|
109
|
-
haml (>= 4.0, < 6)
|
110
|
-
nokogiri (>= 1.6.0)
|
111
|
-
ruby_parser (~> 3.5)
|
112
96
|
i18n (1.8.10)
|
113
97
|
concurrent-ruby (~> 1.0)
|
114
98
|
kaminari (1.2.1)
|
@@ -197,8 +181,6 @@ GEM
|
|
197
181
|
rspec-mocks (~> 3.10)
|
198
182
|
rspec-support (~> 3.10)
|
199
183
|
rspec-support (3.10.2)
|
200
|
-
ruby_parser (3.17.0)
|
201
|
-
sexp_processor (~> 4.15, >= 4.15.1)
|
202
184
|
sass-rails (6.0.0)
|
203
185
|
sassc-rails (~> 2.1, >= 2.1.1)
|
204
186
|
sassc (2.4.0)
|
@@ -209,7 +191,6 @@ GEM
|
|
209
191
|
sprockets (> 3.0)
|
210
192
|
sprockets-rails
|
211
193
|
tilt
|
212
|
-
sexp_processor (4.15.3)
|
213
194
|
sprockets (4.0.2)
|
214
195
|
concurrent-ruby (~> 1.0)
|
215
196
|
rack (> 1, < 3)
|
@@ -218,7 +199,6 @@ GEM
|
|
218
199
|
activesupport (>= 4.0)
|
219
200
|
sprockets (>= 3.0.0)
|
220
201
|
sqlite3 (1.4.2)
|
221
|
-
temple (0.8.2)
|
222
202
|
thor (1.1.0)
|
223
203
|
tilt (2.0.10)
|
224
204
|
turbo-rails (0.8.1)
|
data/README.md
CHANGED
@@ -19,25 +19,19 @@ By default, it generates code that gives users full control over objects they 'o
|
|
19
19
|
|
20
20
|
Hot Glue generates functionality that's quick and dirty. It let's you be crafty. As with a real hot glue gun, use with caution.
|
21
21
|
|
22
|
-
* Build plug-and-play scaffolding
|
23
|
-
*
|
24
|
-
*
|
25
|
-
*
|
26
|
-
*
|
27
|
-
*
|
28
|
-
*
|
29
|
-
*
|
30
|
-
*
|
31
|
-
* Create specs automatically along with the controllers.
|
32
|
-
* Throw the scaffolding away when your app is ready to graduate to its next phase (or don't if you like it).
|
22
|
+
* Build plug-and-play scaffolding mixing generated ERB or HAML with the power of Hotwire and Turbo-Rails
|
23
|
+
* Everything edits-in-place (unless you use --big-edit, then it won't)
|
24
|
+
* Automatically Reads Your Models (make them before building your scaffolding!)
|
25
|
+
* Excellent for CREATE-READ-UPDATE-DELETE (CRUD), lists with pagination (coming soon: searching & sorting)
|
26
|
+
* Great for prototyping, but you should learn Rails fundamentals first.
|
27
|
+
* 'Packaged' with Devise, Kaminari, Rspec, FontAwesome
|
28
|
+
* Create system specs automatically along with the generated code.
|
29
|
+
* Nest your routes model-by-model for built-in poor man's authentication.
|
30
|
+
* Throw the scaffolding away when your app is ready to graduate to its next phase.
|
33
31
|
|
34
32
|
## QUICK START
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
Feel free to build your own tables when you get to the sections for building the 'Event' scaffold:
|
39
|
-
|
40
|
-
https://jasonfleetwoodboldt.com/hot-glue
|
34
|
+
If you like tutorials, try https://jasonfleetwoodboldt.com/hot-glue
|
41
35
|
|
42
36
|
## HOW EASY?
|
43
37
|
|
@@ -54,38 +48,18 @@ Instantly get a simple CRUD interface
|
|
54
48
|
|
55
49
|
![hot-glue-4](https://user-images.githubusercontent.com/59002/116405517-c2b2e300-a7fd-11eb-8423-d43e3afc9fa6.gif)
|
56
50
|
|
51
|
+
# Getting Started
|
57
52
|
|
58
|
-
## ADD HOTWIRE
|
53
|
+
## 1. ADD HOTWIRE
|
54
|
+
(RAILS 6 ONLY— SKIP THIS STEP FOR RAILS 7)
|
59
55
|
```
|
60
56
|
yarn add @hotwired/turbo-rails
|
61
57
|
```
|
62
58
|
or `npm install @hotwired/turbo-rails`
|
63
59
|
|
64
|
-
## ADD HOT-GLUE GEM
|
65
|
-
- Add `gem 'hot-glue'` to your Gemfile & `bundle install`
|
66
|
-
|
67
|
-
## ADD RSPEC, FACTORY-BOT, AND FFAKER
|
68
|
-
|
69
|
-
add these 3 gems to your gemfile inside :development and :test groups
|
70
|
-
```
|
71
|
-
gem 'rspec-rails'
|
72
|
-
gem 'factory_bot_rails'
|
73
|
-
gem 'ffaker'
|
74
|
-
```
|
75
|
-
|
76
|
-
|
77
|
-
## RUN THE RSPEC INSTALLER
|
78
|
-
- run `rails generate rspec:install`
|
79
|
-
|
80
|
-
## RUN HOT-GLUE INSTALL
|
81
|
-
### FOR ERB:
|
82
|
-
`rails generate hot_glue:install --markup=erb`
|
83
60
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
## FOR RAILS 6 ONLY: SWITCH FROM TurblLinks to Turbo-Rails (SKIP THIS STEP FOR RAILS 7)
|
61
|
+
## 2. SWITCH FROM TurblLinks to Turbo-Rails
|
62
|
+
(RAILS 6 ONLY— SKIP THIS STEP FOR RAILS 7)
|
89
63
|
(THIS WAS AUTOMATICALLY DONE BY THE HOT GLUE INSTALLATION -- CONFIRM CHANGES ONLY)
|
90
64
|
- Add `gem 'turbo-rails'` to your Gemfile & `bundle install`
|
91
65
|
- Then install it with `rails turbo:install`
|
@@ -110,7 +84,34 @@ Turbo.start()
|
|
110
84
|
```
|
111
85
|
|
112
86
|
|
113
|
-
##
|
87
|
+
## 3. ADD HOT-GLUE GEM
|
88
|
+
- Add `gem 'hot-glue', '~> 0.2.6'` to your Gemfile & `bundle install`
|
89
|
+
|
90
|
+
(TODO: figure out why bundler seems to install the yanked version 0.0.0 if you don't specify the hot glue version)
|
91
|
+
|
92
|
+
## 4. ADD RSPEC, FACTORY-BOT, AND FFAKER
|
93
|
+
|
94
|
+
add these 3 gems to your gemfile **inside a group for both :development and :test*. Do not add these gems to only the :test group or else your will have problems with the generators.
|
95
|
+
```
|
96
|
+
gem 'rspec-rails'
|
97
|
+
gem 'factory_bot_rails'
|
98
|
+
gem 'ffaker'
|
99
|
+
```
|
100
|
+
|
101
|
+
- run `rails generate rspec:install`
|
102
|
+
|
103
|
+
## 5(A). RUN HOT-GLUE INSTALL
|
104
|
+
### FOR ERB:
|
105
|
+
`rails generate hot_glue:install --markup=erb`
|
106
|
+
|
107
|
+
### FOR HAML:
|
108
|
+
`rails generate hot_glue:install --markup=haml`
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
## 5(B). Modify `application.html.erb`
|
114
115
|
(THIS WAS AUTOMATICALLY DONE BY THE HOT GLUE INSTALLATION -- CONFIRM CHANGES ONLY)
|
115
116
|
Note: if you have some kind of non-standard application layout, like one at a different file
|
116
117
|
or if you have modified your opening <body> tag, this may not have been automatically applied by the installer.
|
@@ -120,7 +121,7 @@ or if you have modified your opening <body> tag, this may not have been automati
|
|
120
121
|
<%= render partial: 'layouts/flash_notices' %>
|
121
122
|
```
|
122
123
|
|
123
|
-
## Modify `rails_helper.rb`
|
124
|
+
## 5(C). Modify `rails_helper.rb`
|
124
125
|
(THIS WAS AUTOMATICALLY DONE BY THE HOT GLUE INSTALLATION)
|
125
126
|
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`
|
126
127
|
this may not have been automatically applied by the installer.
|
@@ -134,7 +135,7 @@ this may not have been automatically applied by the installer.
|
|
134
135
|
```
|
135
136
|
|
136
137
|
|
137
|
-
## CAPYBARA: SWITCH FROM RACK-TEST TO HEADLESS CHROME
|
138
|
+
## 5(D) CAPYBARA: SWITCH FROM RACK-TEST TO HEADLESS CHROME
|
138
139
|
(THIS WAS AUTOMATICALLY DONE BY THE HOT GLUE INSTALLATION)
|
139
140
|
|
140
141
|
- By default Capybara is installed with :rack_test as its driver.
|
@@ -145,14 +146,11 @@ By default, Capybara uses the :rack_test driver, which is fast but limited: it d
|
|
145
146
|
```
|
146
147
|
|
147
148
|
- To fix this, you must switch to a Javascript-supporting Capybara driver. You can choose one of:
|
148
|
-
-
|
149
|
-
```
|
150
|
-
Capybara.default_driver = :selenium
|
151
|
-
```
|
152
149
|
|
153
|
-
|
154
|
-
Capybara.default_driver = :selenium_chrome
|
155
|
-
|
150
|
+
`Capybara.default_driver = :selenium`
|
151
|
+
`Capybara.default_driver = :selenium_chrome`
|
152
|
+
`Capybara.default_driver = :selenium_chrome_headless`
|
153
|
+
|
156
154
|
By default, the installer should have added this option to your `rails_helper.rb` file:
|
157
155
|
|
158
156
|
```
|
@@ -177,38 +175,12 @@ Alternatively, can define your own driver like so:
|
|
177
175
|
Capybara.default_driver = :my_headless_chrome_desktop
|
178
176
|
|
179
177
|
```
|
180
|
-
|
181
|
-
## Add User Authentication if you are using Access Control
|
182
|
-
(THIS WAS AUTOMATICALLY DONE BY THE HOT GLUE INSTALLATION)
|
183
|
-
|
184
|
-
- for a quick Capybara login, create a support helper in `spec/support/` and log-in as your user
|
185
|
-
- in the default code, the devise login would be for an object called account and lives at the route `/accounts/sign_in`
|
186
|
-
- modify the generated code (it was installed by the installed) for your devise login
|
187
|
-
```
|
188
|
-
def login_as(account)
|
189
|
-
visit '/accounts/sign_in'
|
190
|
-
within("#new_account") do
|
191
|
-
fill_in 'Email', with: account.email
|
192
|
-
fill_in 'Password', with: 'password'
|
193
|
-
end
|
194
|
-
click_button 'Log in'
|
195
|
-
end
|
196
|
-
```
|
197
|
-
|
198
|
-
## Install Bootstrap using Sprockets (IMPORTANT: YOU DO NOT NEED JQUERY)
|
199
178
|
|
200
|
-
Bootstrap with Sprockets for Rails 5 or 7 default — Rails 6 custom
|
201
|
-
- add `gem 'bootstrap-rubygem'` to your gemfile
|
202
|
-
- replace `application.css` with a new file (delete old contents) `application.scss`
|
203
|
-
```
|
204
|
-
@import "bootstrap";
|
205
|
-
```
|
206
|
-
- see README at github.com/twbs/bootstrap-rubygem to install
|
207
179
|
|
208
|
-
|
209
|
-
|
180
|
+
### 6(A) Bootstrap with Webpack:
|
181
|
+
DO EIETHER 6(A) OR 6(B)
|
210
182
|
- add to Gemfile
|
211
|
-
- gem 'bootstrap', '~> 5.1.
|
183
|
+
- `gem 'bootstrap', '~> 5.1.3'`
|
212
184
|
- completely delete the file `app/assets/application.css`
|
213
185
|
- create new file where it was `app/assets/application.scss` with this contents (do not keep the contents of the old application.css file):
|
214
186
|
```
|
@@ -218,7 +190,7 @@ Bootstrap with Sprockets for Rails 5 or 7 default — Rails 6 custom
|
|
218
190
|
|
219
191
|
* You do not need jQuery for HotGlue to work *
|
220
192
|
|
221
|
-
|
193
|
+
### Hook your Bootstrap into your global application scss
|
222
194
|
- change `stylesheet_link_tag` to `stylesheet_pack_tag` in your application layout
|
223
195
|
- run `yarn add bootstrap`
|
224
196
|
- create a new file at `app/javascript/require_bootstrap.scss` with this content
|
@@ -231,16 +203,48 @@ Bootstrap with Sprockets for Rails 5 or 7 default — Rails 6 custom
|
|
231
203
|
import 'require_bootstrap'
|
232
204
|
```
|
233
205
|
|
234
|
-
|
206
|
+
|
207
|
+
## 6(B) Install Bootstrap using Sprockets
|
208
|
+
(IMPORTANT: YOU DO NOT NEED JQUERY)
|
209
|
+
DO EIETHER 6(A) OR 6(B)
|
210
|
+
|
211
|
+
Bootstrap with Sprockets for Rails 5 or 7 default — Rails 6 custom
|
212
|
+
- add `gem 'bootstrap-rubygem'` to your gemfile
|
213
|
+
- replace `application.css` with a new file (delete old contents) `application.scss`
|
214
|
+
```
|
215
|
+
@import "bootstrap";
|
216
|
+
```
|
217
|
+
- see README at github.com/twbs/bootstrap-rubygem to install
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
## 7. install font-awesome
|
223
|
+
|
224
|
+
I recommend https://github.com/tomkra/font_awesome5_rails
|
225
|
+
or https://github.com/FortAwesome/font-awesome-sass
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
## 8. For Enum support, I recommend activerecord-pg_enum
|
230
|
+
|
231
|
+
Instructions for Rails are here:
|
232
|
+
https://jasonfleetwoodboldt.com/courses/stepping-up-rails/enumerated-types-in-rails-and-postgres/
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
## 9. Devise
|
235
237
|
(or only use --gd mode, see below)
|
236
238
|
|
237
239
|
Add to your Gemfile `gem 'devise'`
|
238
240
|
|
241
|
+
|
242
|
+
|
239
243
|
```
|
240
244
|
rails generate devise:install
|
241
245
|
```
|
242
246
|
|
243
|
-
|
247
|
+
IMPORTANT: Follow the instructions the Devise installer gives you, *Except Step 3*, you can skip this step:
|
244
248
|
```
|
245
249
|
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
|
246
250
|
For example:
|
@@ -251,7 +255,7 @@ IMPORTNAT: Follow the instructions the Devise installer gives you, *Except Step
|
|
251
255
|
```
|
252
256
|
|
253
257
|
|
254
|
-
You can also skip Devise Step 4, which is optional:
|
258
|
+
You can also skip Devise installer Step 4, which is optional:
|
255
259
|
```
|
256
260
|
4. You can copy Devise views (for customization) to your app by running:
|
257
261
|
|
@@ -261,25 +265,32 @@ You can also skip Devise Step 4, which is optional:
|
|
261
265
|
```
|
262
266
|
|
263
267
|
|
264
|
-
##
|
265
|
-
|
266
|
-
|
267
|
-
## install font-awesome
|
268
|
-
|
269
|
-
I recommend https://github.com/tomkra/font_awesome5_rails
|
270
|
-
or https://github.com/FortAwesome/font-awesome-sass
|
268
|
+
## 9(B) Devise & Capybara - Add User Authentication if you are using Access Control
|
269
|
+
(THIS WAS AUTOMATICALLY DONE BY THE HOT GLUE INSTALLATION)
|
271
270
|
|
271
|
+
- for a quick Capybara login, create a support helper in `spec/support/` and log-in as your user
|
272
|
+
- in the default code, the devise login would be for an object called account and lives at the route `/accounts/sign_in`
|
273
|
+
- modify the generated code (it was installed by the installed) for your devise login
|
274
|
+
```
|
275
|
+
def login_as(account)
|
276
|
+
visit '/accounts/sign_in'
|
277
|
+
within("#new_account") do
|
278
|
+
fill_in 'Email', with: account.email
|
279
|
+
fill_in 'Password', with: 'password'
|
280
|
+
end
|
281
|
+
click_button 'Log in'
|
282
|
+
end
|
283
|
+
```
|
272
284
|
|
273
285
|
|
274
|
-
##
|
286
|
+
## RAILS 7: Devise is not yet supported on Rails 7 unless you use the master branch of devise
|
275
287
|
|
276
|
-
Instructions for Rails are here:
|
277
|
-
https://jasonfleetwoodboldt.com/courses/stepping-up-rails/enumerated-types-in-rails-and-postgres/
|
278
288
|
|
279
289
|
|
290
|
+
# HOT GLUE DOCS
|
280
291
|
|
281
292
|
|
282
|
-
|
293
|
+
## First Argument
|
283
294
|
(no double slash)
|
284
295
|
|
285
296
|
TitleCase class name of the thing you want to build a scaffoling for.
|
@@ -549,6 +560,31 @@ Omits delete action.
|
|
549
560
|
|
550
561
|
If you do not want inline editing of your list items but instead to fall back to full page style behavior for your edit views, use `--big-edit`. Turbo still handles the page interactions, but the user is taken to a full-screen edit page instead of an edit-in-place interaction.
|
551
562
|
|
563
|
+
### `--display-list-after-update` (default: false)
|
564
|
+
|
565
|
+
After an update-in-place normally only the edit view is swapped out for the show view of the record you just edited.
|
566
|
+
|
567
|
+
Sometimes you might want to redisplay the entire list after you make an update (for example, if your action removes that record from the result set).
|
568
|
+
|
569
|
+
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.
|
570
|
+
|
571
|
+
|
572
|
+
|
573
|
+
### `--downnest`
|
574
|
+
(2021-11-23 - WIP)
|
575
|
+
|
576
|
+
Automatically create subviews down your object tree. This should be the name of a has_many relationship based from the current object.
|
577
|
+
You will need to build scaffolding with the same name for the related object as well.
|
578
|
+
On the list view, the object you are currently building will be built with a sub-view list of the objects related from the given line.
|
579
|
+
|
580
|
+
### `--nestable` (default: false)
|
581
|
+
(2021-11-23 - WIP)
|
582
|
+
When creating a controller that you will use a another controllers downnest (that is, you will display related records-- like a portal-- from the parent within each row of the parent's list view), set nestable to true.
|
583
|
+
|
584
|
+
If the cooresponding Rails route contains nesting and this controller is downnested by someone else, you'll want to set nestable to true.
|
585
|
+
|
586
|
+
If the cooresponding Rails route is not nested and the controller sits a the root of the namespace, set nestable to false.
|
587
|
+
|
552
588
|
|
553
589
|
## Automatic Base Controller
|
554
590
|
|
@@ -564,17 +600,23 @@ Obviously, the created controller will always have this base controller as its s
|
|
564
600
|
- Text*
|
565
601
|
- Float*
|
566
602
|
- Datetime
|
567
|
-
- Date
|
568
|
-
- Time
|
603
|
+
- Date
|
604
|
+
- Time
|
569
605
|
- Boolean
|
570
|
-
- Enum - will
|
571
|
-
|
606
|
+
- Enum - will display as a value list populated from the enum list defined on your model. see https://jasonfleetwoodboldt.com/courses/stepping-up-rails/enumerated-types-in-rails-and-postgres/
|
607
|
+
|
572
608
|
* shows in a size-aware container, i.e. in a bigger box if the field allows for more content
|
573
609
|
|
574
610
|
|
575
611
|
|
576
612
|
# VERSION HISTORY
|
577
613
|
|
614
|
+
#### 2021-11-27 - v0.2.9E — EXPERIMENTAL
|
615
|
+
- Downnesting
|
616
|
+
- Adds spec coverage support for enums
|
617
|
+
- Several more fixes; this is preparation for forthcoming release.
|
618
|
+
- Some parts still experimental. Use with caution.
|
619
|
+
|
578
620
|
#### 2021-10-11 - v0.2.6 - many additional automatic fixes for default Rails installation 6 or 7 for the generate hot_glue:install command
|
579
621
|
|
580
622
|
|
@@ -623,6 +665,20 @@ Obviously, the created controller will always have this base controller as its s
|
|
623
665
|
|
624
666
|
#### 2021-02-23 - v0.0.0 - Port of my prior work from github.com/jasonfb/common_core_js
|
625
667
|
|
668
|
+
# PROBLEMS
|
669
|
+
|
670
|
+
Here are some defeciencies to note
|
671
|
+
|
672
|
+
- [ ] the ERB output has a necessary gsub that makes it so that every file always kicks the "Overwrite?" even when it has not changed. Unfortunately because of the meta programming involved in the ERB, I do not see a way around this although I would like to eventually fix it or match the AR generator internals to fix this problem.
|
673
|
+
|
674
|
+
- [ ] the system_spec that is generated (system/*_spec.rb) works most of the time but obviously you must run it to confirm it passes correclty. still working out bugs in this area for special cases.
|
675
|
+
|
676
|
+
|
677
|
+
|
678
|
+
- [ ] Note that the specs use FFaker data and random numbers, so if you have model-level validations and out-of-bounds choices are made, your specs might fail *intermittently*.
|
679
|
+
---> I know I hate intermittent failing specs, and if I had any in my app I would surely refactor them out. I'm not sure how I feel about *randomized* data-- or this much randomized data-- in specs. It's kind of fun but it also is tempting fate somewhat, and hopefully encouraging/forcing you to refactor them to be meaningful to your models and model-level validations.
|
680
|
+
|
681
|
+
- [ ] The specs themselves and some generated code is particularly ugly-- especially, formated inconsistently. Sorry about this, will clean this up soon. It is there to encourage you to read the generated code and lint or rubocop it before you check it in. I know the indentation is off and very ugly.
|
626
682
|
|
627
683
|
|
628
684
|
# HOW THIS GEM IS TESTED
|
@@ -12,6 +12,20 @@ module HotGlue
|
|
12
12
|
end
|
13
13
|
|
14
14
|
|
15
|
+
def magic_button_output(*args)
|
16
|
+
path_helper_singular = args[0][:path_helper_singular]
|
17
|
+
path_helper_args = args[0][:path_helper_args]
|
18
|
+
singular = args[0][:singular]
|
19
|
+
magic_buttons = args[0][:magic_buttons]
|
20
|
+
|
21
|
+
magic_buttons.collect{ |button_name|
|
22
|
+
"<%= form_with model: #{singular}, url: #{path_helper_singular}(#{path_helper_args}) do |f| %>
|
23
|
+
<%= f.hidden_field :#{button_name}, value: \"#{button_name}\" %>
|
24
|
+
<%= f.submit '#{button_name.titleize}'.html_safe, data: {confirm: 'Are you sure you want to #{button_name} this #{singular}?'}, class: '#{singular}-button btn btn-primary ' %>
|
25
|
+
<% end %>"
|
26
|
+
}.join("\n")
|
27
|
+
end
|
28
|
+
|
15
29
|
def text_area_output(col, field_length, col_identifier )
|
16
30
|
lines = field_length % 40
|
17
31
|
if lines > 5
|
@@ -125,9 +139,11 @@ module HotGlue
|
|
125
139
|
" <%= f.label(:#{col.to_s}, value: 'Yes', for: '#{singular}_#{col.to_s}_1') %>\n" +
|
126
140
|
"</div>"
|
127
141
|
when :enum
|
128
|
-
enum_name ="enum_name"
|
142
|
+
enum_name = "enum_name"
|
143
|
+
# byebug
|
144
|
+
enum_type = eval("#{singular_class}.columns.select{|x| x.name == '#{col.to_s}'}[0].sql_type")
|
129
145
|
"<div class='#{col_identifier} form-group <%= 'alert-danger' if #{singular}.errors.details.keys.include?(:#{col.to_s}) %>' >
|
130
|
-
<%= f.collection_select(:#{col.to_s}, enum_to_collection_select( #{singular_class}.defined_enums['#{
|
146
|
+
<%= f.collection_select(:#{col.to_s}, enum_to_collection_select( #{singular_class}.defined_enums['#{enum_type}']), :key, :value, {prompt: true, selected: @#{singular}.#{col.to_s} }, class: 'form-control') %>
|
131
147
|
<label class='small form-text text-muted'>#{col.to_s.humanize}</label></div>"
|
132
148
|
|
133
149
|
end
|
@@ -250,4 +266,5 @@ module HotGlue
|
|
250
266
|
|
251
267
|
|
252
268
|
|
269
|
+
|
253
270
|
end
|
@@ -64,7 +64,7 @@ module HotGlue
|
|
64
64
|
exit_message= "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
65
65
|
exit
|
66
66
|
end
|
67
|
-
display_column = derrive_reference_name(assoc.class_name)
|
67
|
+
display_column = HotGlue.derrive_reference_name(assoc.class_name)
|
68
68
|
|
69
69
|
|
70
70
|
"#{col_identifier}{class: \"form-group \#{'alert-danger' if #{singular}.errors.details.keys.include?(:#{assoc_name.to_s})}\"}
|
@@ -162,7 +162,7 @@ module HotGlue
|
|
162
162
|
raise(HotGlue::Error,exit_message)
|
163
163
|
end
|
164
164
|
|
165
|
-
display_column = derrive_reference_name(assoc.class_name)
|
165
|
+
display_column = HotGlue.derrive_reference_name(assoc.class_name)
|
166
166
|
|
167
167
|
|
168
168
|
"#{col_identifer}
|
@@ -31,7 +31,7 @@ module HotGlue
|
|
31
31
|
end
|
32
32
|
|
33
33
|
class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
34
|
-
|
34
|
+
hook_for :form_builder, :as => :scaffold
|
35
35
|
|
36
36
|
source_root File.expand_path('templates', __dir__)
|
37
37
|
attr_accessor :path, :singular, :plural, :singular_class, :nest_with
|
@@ -51,21 +51,16 @@ module HotGlue
|
|
51
51
|
class_option :no_specs, type: :boolean, default: false
|
52
52
|
class_option :no_delete, type: :boolean, default: false
|
53
53
|
class_option :no_create, type: :boolean, default: false
|
54
|
+
class_option :no_edit, type: :boolean, default: false
|
54
55
|
class_option :no_paginate, type: :boolean, default: false
|
55
56
|
class_option :big_edit, type: :boolean, default: false
|
56
57
|
class_option :show_only, type: :string, default: ""
|
57
58
|
class_option :markup, type: :string, default: "erb"
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# if @template_builder.is_a?(HotGlue::ErbTemplate)
|
64
|
-
# @output_buffer.gsub!('\%', '%')
|
65
|
-
# end
|
66
|
-
# end
|
67
|
-
|
68
|
-
|
59
|
+
class_option :stimulus_syntax, type: :boolean, default: nil
|
60
|
+
class_option :downnest, type: :string, default: nil
|
61
|
+
class_option :nestable, type: :boolean, default: false
|
62
|
+
class_option :magic_buttons, type: :string, default: nil
|
63
|
+
class_option :display_list_after_update, type: :boolean, default: false
|
69
64
|
|
70
65
|
def initialize(*meta_args)
|
71
66
|
super
|
@@ -114,6 +109,7 @@ module HotGlue
|
|
114
109
|
|
115
110
|
@singular_class = @singular.titleize.gsub(" ", "")
|
116
111
|
@exclude_fields = []
|
112
|
+
|
117
113
|
@exclude_fields += options['exclude'].split(",").collect(&:to_sym)
|
118
114
|
|
119
115
|
if !options['include'].empty?
|
@@ -138,6 +134,13 @@ module HotGlue
|
|
138
134
|
@no_paginate = options['no_paginate'] || false
|
139
135
|
@big_edit = options['big_edit']
|
140
136
|
|
137
|
+
@no_edit = options['no_edit'] || false
|
138
|
+
@display_list_after_update = options['display_list_after_update'] || false
|
139
|
+
|
140
|
+
|
141
|
+
@downnest_relationship = options['downnest'] || false
|
142
|
+
|
143
|
+
|
141
144
|
if @god
|
142
145
|
@auth = nil
|
143
146
|
end
|
@@ -156,8 +159,16 @@ module HotGlue
|
|
156
159
|
end
|
157
160
|
end
|
158
161
|
|
159
|
-
|
160
|
-
|
162
|
+
|
163
|
+
@magic_buttons = []
|
164
|
+
if options['magic_buttons']
|
165
|
+
@magic_buttons = options['magic_buttons'].split(',')
|
166
|
+
end
|
167
|
+
|
168
|
+
@build_update_action = !@no_edit || !@magic_buttons.empty?
|
169
|
+
# if the magic buttons are present, build the update action anyway
|
170
|
+
|
171
|
+
@nestable = options['nestable'] || false
|
161
172
|
|
162
173
|
if @auth && ! @self_auth && @nested_args.none?
|
163
174
|
@object_owner_sym = @auth.gsub("current_", "").to_sym
|
@@ -173,6 +184,8 @@ module HotGlue
|
|
173
184
|
end
|
174
185
|
end
|
175
186
|
|
187
|
+
|
188
|
+
|
176
189
|
@reference_name = HotGlue.derrive_reference_name(singular_class)
|
177
190
|
|
178
191
|
identify_object_owner
|
@@ -383,24 +396,32 @@ module HotGlue
|
|
383
396
|
end
|
384
397
|
|
385
398
|
def path_helper_args
|
386
|
-
if @nested_args.any?
|
387
|
-
[(@nested_args).collect{|a| "
|
399
|
+
if @nested_args.any? && @nestable
|
400
|
+
[(@nested_args).collect{|a| "#{a}"} , singular].join(",")
|
388
401
|
else
|
389
402
|
singular
|
390
403
|
end
|
391
404
|
end
|
392
405
|
|
393
406
|
def path_helper_singular
|
394
|
-
|
407
|
+
if @nestable
|
408
|
+
"#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{singular}_path"
|
409
|
+
else
|
410
|
+
"#{@namespace+"_" if @namespace}#{singular}_path"
|
411
|
+
end
|
395
412
|
end
|
396
413
|
|
397
414
|
def path_helper_plural
|
398
|
-
|
415
|
+
if ! @nestable
|
416
|
+
"#{@namespace+"_" if @namespace}#{plural}_path"
|
417
|
+
else
|
418
|
+
"#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{plural}_path"
|
419
|
+
end
|
399
420
|
end
|
400
421
|
|
401
422
|
def path_arity
|
402
423
|
res = ""
|
403
|
-
if @nested_args.any?
|
424
|
+
if @nested_args.any? && @nestable
|
404
425
|
res << nested_objects_arity + ", "
|
405
426
|
end
|
406
427
|
res << "@" + singular
|
@@ -419,28 +440,37 @@ module HotGlue
|
|
419
440
|
end
|
420
441
|
|
421
442
|
def new_path_name
|
422
|
-
|
423
443
|
base = "new_#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_") if @nested_args.any?}#{singular}_path"
|
424
444
|
if @nested_args.any?
|
425
445
|
base += "(" + @nested_args.collect { |arg|
|
426
|
-
"
|
446
|
+
"#{arg}.id"
|
427
447
|
}.join(", ") + ")"
|
428
448
|
end
|
429
449
|
base
|
430
450
|
end
|
431
451
|
|
432
452
|
def nested_assignments
|
453
|
+
return "" if @nested_args.none?
|
454
|
+
@nested_args.map{|a| "#{a}: #{a}"}.join(", ") #metaprgramming into Ruby hash
|
455
|
+
end
|
456
|
+
|
457
|
+
def nested_assignments_top_level # this is by accessing the instance variable-- only use at top level
|
433
458
|
@nested_args.map{|a| "#{a}: @#{a}"}.join(", ") #metaprgramming into Ruby hash
|
434
459
|
end
|
435
460
|
|
436
|
-
|
461
|
+
|
462
|
+
def nest_assignments_operator(top_level = false, leading_comma = false)
|
437
463
|
if @nested_args.any?
|
438
|
-
", #{nested_assignments}"
|
464
|
+
"#{', ' if leading_comma}#{top_level ? nested_assignments_top_level : nested_assignments }"
|
439
465
|
else
|
440
466
|
""
|
441
467
|
end
|
442
468
|
end
|
443
469
|
|
470
|
+
def nested_assignments_with_leading_comma
|
471
|
+
nest_assignments_operator(false, true)
|
472
|
+
end
|
473
|
+
|
444
474
|
def nested_objects_arity
|
445
475
|
@nested_args.map{|a| "@#{a}"}.join(", ")
|
446
476
|
end
|
@@ -492,6 +522,15 @@ module HotGlue
|
|
492
522
|
!Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name }['devise']
|
493
523
|
end
|
494
524
|
|
525
|
+
|
526
|
+
def magic_button_output
|
527
|
+
@template_builder.magic_button_output(
|
528
|
+
path_helper_singular: path_helper_singular,
|
529
|
+
path_helper_args: path_helper_args,
|
530
|
+
singular: singular,
|
531
|
+
magic_buttons: @magic_buttons
|
532
|
+
)
|
533
|
+
end
|
495
534
|
# def erb_replace_ampersands!(filename = nil)
|
496
535
|
#
|
497
536
|
# return if filename.nil?
|
@@ -654,24 +693,35 @@ module HotGlue
|
|
654
693
|
else
|
655
694
|
""
|
656
695
|
end
|
657
|
-
|
696
|
+
end
|
658
697
|
|
659
|
-
|
698
|
+
def paginate
|
660
699
|
@template_builder.paginate(plural: plural)
|
661
|
-
|
700
|
+
end
|
662
701
|
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
702
|
+
def delete_confirmation_syntax
|
703
|
+
if !@stimulus_syntax
|
704
|
+
"{confirm: 'Are you sure?'}"
|
705
|
+
else
|
706
|
+
"{controller: 'confirmable', 'confirm-message': \"Are you sure you want to delete \#{ #{@singular}.#{ display_class } } \", 'action': 'confirmation#confirm'}"
|
707
|
+
end
|
668
708
|
end
|
669
|
-
end
|
670
709
|
|
671
710
|
|
672
|
-
|
673
|
-
|
711
|
+
def controller_magic_button_update_actions
|
712
|
+
@magic_buttons.collect{ |magic_button|
|
713
|
+
" @#{singular}.#{magic_button}! if #{singular}_params[:#{magic_button}]"
|
714
|
+
}.join("\n")
|
715
|
+
end
|
674
716
|
|
717
|
+
def controller_update_params_tap_away_magic_buttons
|
718
|
+
@magic_buttons.collect{ |magic_button|
|
719
|
+
".tap{ |ary| ary.delete('#{magic_button}') }"
|
720
|
+
}.join("")
|
721
|
+
end
|
722
|
+
|
723
|
+
private # thor does something fancy like sending the class all of its own methods during some strange run sequence
|
724
|
+
# does not like public methods
|
675
725
|
def cc_filename_with_extensions(name, file_format = format)
|
676
726
|
[name, file_format].compact.join(".")
|
677
727
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
class <%= controller_class_name %> < <%= controller_descends_from %>
|
2
|
-
|
2
|
+
helper :hot_glue
|
3
|
+
include HotGlue::ControllerHelper
|
3
4
|
|
5
|
+
<% unless @auth_identifier == '' || @god %>before_action :authenticate_<%= @auth_identifier %>!<% end %>
|
4
6
|
<% if any_nested? %><% nest_chain = [] %> <% @nested_args.each { |arg|
|
5
7
|
this_scope = nest_chain.empty? ? "#{@auth ? auth_object : class_name}.#{arg}s" : "#{nest_chain.last}.#{arg}s"
|
6
8
|
nest_chain << arg %>
|
@@ -9,15 +11,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
9
11
|
before_action :load_<%= singular_name %>, only: [:show, :edit, :update, :destroy]
|
10
12
|
after_action -> { flash.discard }, if: -> { request.format.symbol == :turbo_stream }
|
11
13
|
|
12
|
-
helper :hot_glue
|
13
|
-
include HotGlue::ControllerHelper
|
14
|
-
|
15
14
|
<% if no_devise_installed %>
|
16
15
|
# TODO: implement current_user or use Devise
|
17
16
|
<% end %>
|
18
17
|
|
19
|
-
|
20
|
-
|
21
18
|
<% if any_nested? %><% nest_chain = [] %> <% @nested_args.each { |arg|
|
22
19
|
if !@god
|
23
20
|
this_scope = nest_chain.empty? ? "#{@auth ? auth_object : class_name}.#{arg}s" : "#{nest_chain.last}.#{arg}s"
|
@@ -79,34 +76,37 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
79
76
|
format.html
|
80
77
|
end
|
81
78
|
end
|
82
|
-
end
|
79
|
+
end
|
83
80
|
|
84
|
-
def show
|
81
|
+
<% end %> def show
|
85
82
|
respond_to do |format|
|
86
83
|
format.html
|
87
84
|
end
|
88
85
|
end
|
89
86
|
|
90
|
-
def edit
|
87
|
+
<% unless @no_edit %> def edit
|
91
88
|
respond_to do |format|
|
92
89
|
format.turbo_stream
|
93
90
|
format.html
|
94
91
|
end
|
95
92
|
end
|
96
93
|
|
97
|
-
def update
|
98
|
-
|
94
|
+
<% end %><% if @build_update_action %> def update
|
95
|
+
<%= controller_magic_button_update_actions %>
|
96
|
+
|
97
|
+
if @<%= singular_name %>.update(modify_date_inputs_on_params(<%= singular %>_params<%= @auth ? ', ' + @auth : '' %>)<%= controller_update_params_tap_away_magic_buttons %>)
|
99
98
|
flash[:notice] = "Saved #{@<%= singular %>.<%= display_class %>}"
|
100
99
|
else
|
101
100
|
flash[:alert] = "<%= singular_name.titlecase %> could not be saved."
|
102
101
|
end
|
102
|
+
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
103
103
|
respond_to do |format|
|
104
104
|
format.turbo_stream
|
105
105
|
format.html
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
<% if destroy_action %> def destroy
|
109
|
+
<% end %><% if destroy_action %> def destroy
|
110
110
|
begin
|
111
111
|
@<%=singular_name%>.destroy
|
112
112
|
rescue StandardError => e
|
@@ -117,10 +117,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
117
117
|
format.turbo_stream
|
118
118
|
format.html { redirect_to <%= path_helper_plural %> }
|
119
119
|
end
|
120
|
-
end
|
120
|
+
end
|
121
121
|
|
122
|
-
|
123
|
-
params.require(:<%=singular_name%>).permit( <%= @columns %> )
|
122
|
+
<% end %>def <%=singular_name%>_params
|
123
|
+
params.require(:<%=singular_name%>).permit( <%= @columns + @magic_buttons.collect(&:to_sym) %> )
|
124
124
|
end
|
125
125
|
|
126
126
|
def default_colspan
|
@@ -128,18 +128,12 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def namespace
|
131
|
-
<% if @namespace %>
|
132
|
-
"<%= @namespace %>/"
|
133
|
-
<% else %>
|
134
|
-
""
|
135
|
-
<% end %>
|
131
|
+
<% if @namespace %>"<%= @namespace %>/" <% else %>""<% end %>
|
136
132
|
end
|
137
133
|
|
138
|
-
|
139
134
|
def common_scope
|
140
135
|
@nested_args
|
141
136
|
end
|
142
|
-
|
143
137
|
end
|
144
138
|
|
145
139
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
<\%= turbo_frame_tag "<%= singular %>__#{ <%= singular %>.id }" do %>
|
3
3
|
<div class='row' data-id='<\%= <%= singular %>.id %>' data-edit='false'>
|
4
|
-
<\%= render partial: '<%= show_path_partial %>', locals: { <%= singular %>: <%= singular %>} %>
|
4
|
+
<\%= render partial: '<%= show_path_partial %>', locals: { <%= singular %>: <%= singular %><%= nest_assignments_operator(false, true) if @nestable %> } %>
|
5
5
|
</div>
|
6
6
|
<\% end %>
|
7
7
|
|
@@ -1,5 +1,13 @@
|
|
1
1
|
<\%= turbo_frame_tag "<%= plural %>-list" do %>
|
2
|
-
<div class="container-fluid "
|
2
|
+
<div class="container-fluid ">
|
3
|
+
<h4><%= plural.gsub("_", " ").upcase %></h4>
|
4
|
+
<div class="row">
|
5
|
+
<div class="col-md-12">
|
6
|
+
<% unless @no_create %><%= '<%= render partial: "' + ((@namespace+"/" if @namespace) || "") + plural + '/new_button", locals: {' + nested_assignments + '}' + '%\>'.gsub('\\',"") %><% end %>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
|
3
11
|
<div class="row">
|
4
12
|
<%= list_column_headings %>
|
5
13
|
<div class='col buttons-col'></div>
|
@@ -11,7 +19,7 @@
|
|
11
19
|
</div>
|
12
20
|
<\% end %>
|
13
21
|
<\% <%= plural %>.each do |<%= singular %>| %>
|
14
|
-
<\%= render partial: '<%= line_path_partial %>', locals: {<%= singular %>: <%= singular
|
22
|
+
<\%= render partial: '<%= line_path_partial %>', locals: {<%= singular %>: <%= singular %><%= nested_assignments_with_leading_comma if @nestable %> } %>
|
15
23
|
<\% end %>
|
16
24
|
|
17
25
|
<%= @no_paginate ? "" : paginate %>
|
@@ -1,8 +1,24 @@
|
|
1
1
|
<%= all_line_fields %>
|
2
|
+
|
3
|
+
<% if @downnest_relationship %>
|
4
|
+
<div class="col">
|
5
|
+
<\%= render partial: "dashboard/<%= @downnest_relationship %>/list", locals: {
|
6
|
+
<%= @singular %>: <%= @singular %>,
|
7
|
+
<%= @downnest_relationship %>: <%= @singular %>.<%= @downnest_relationship %>} %>
|
8
|
+
</div>
|
9
|
+
<% end %>
|
10
|
+
|
2
11
|
<div class="col">
|
3
12
|
<% if destroy_action %>
|
4
|
-
<\%=
|
13
|
+
<\%= form_with url: <%= path_helper_singular %>(<%= path_helper_args %>), method: :delete do |f| %>
|
14
|
+
<\%= f.submit "Delete".html_safe, data: <%= delete_confirmation_syntax %>, class: "delete-<%= singular %>-button btn btn-primary " %>
|
15
|
+
<\% end %>
|
5
16
|
<% end %>
|
6
|
-
|
17
|
+
|
18
|
+
|
19
|
+
<%= magic_button_output %>
|
20
|
+
|
21
|
+
<% unless @no_edit %>
|
7
22
|
<\%= link_to "Edit <i class='fa fa-1x fa-list-alt'></i>".html_safe, edit_<%= path_helper_singular %>(<%= path_helper_args %>), <% if @big_edit %>'data-turbo' => 'false', <% end %>disable_with: "Loading...", class: "edit-<%= singular %>-button btn btn-primary " %>
|
23
|
+
<% end %>
|
8
24
|
</div>
|
@@ -1,13 +1,13 @@
|
|
1
1
|
<\% if @<%= singular %>.errors.none? %>
|
2
2
|
<\%= turbo_stream.replace "<%= plural %>-list" do %>
|
3
|
-
<\%= render partial: "list", locals: {<%= plural %>: @<%= plural %>} %>
|
3
|
+
<\%= render partial: "list", locals: {<%= plural %>: @<%= plural %> <%= nest_assignments_operator(true, true) %>} %>
|
4
4
|
<\% end %>
|
5
5
|
<\% end %>
|
6
6
|
<\%= turbo_stream.replace "<%= singular %>-new" do %>
|
7
7
|
<\% if @<%= singular %>.errors.none? %>
|
8
|
-
<\%= render partial: "new_button" %>
|
8
|
+
<\%= render partial: "new_button", locals: {<%= nest_assignments_operator(true, false) %>} %>
|
9
9
|
<\% else %>
|
10
|
-
<\%= render partial: "new_form", locals: {<%= singular %>: @<%= singular %>} %>
|
10
|
+
<\%= render partial: "new_form", locals: {<%= singular %>: @<%= singular %> <%= nest_assignments_operator(true, true) %> } %>
|
11
11
|
<\% end %>
|
12
12
|
<\% end %>
|
13
13
|
<\%= turbo_stream.replace "flash_notices" do %>
|
@@ -5,17 +5,14 @@
|
|
5
5
|
<div class="cell editable" style="position: relative;">
|
6
6
|
|
7
7
|
<\% if @<%= singular %>.errors.any? %>
|
8
|
-
<\%= render(partial: "#{controller.namespace}errors", locals: {resource: @<%= singular%> }) %>
|
8
|
+
<\%= render(partial: "#{controller.namespace}errors", locals: {resource: @<%= singular %> }) %>
|
9
9
|
<\% end %>
|
10
10
|
|
11
11
|
<h2>Editing <\%= @<%= @singular %>.<%= display_class %> %></h2>
|
12
12
|
<\%= form_with model: <%= "@" + singular%>, url: <%= path_helper_singular %>(<%= path_arity %>) do |f| %>
|
13
13
|
<\%= render partial: "form", locals: {:<%= singular %> => <%= "@" + singular%>, f: f} %>
|
14
14
|
<\% end %>
|
15
|
-
|
16
|
-
data-name='close-<%= singular %>__<\% <%= "@" + singular %>.id %> }'
|
17
|
-
data-row-id=<%= "@" + singular %>.id,
|
18
|
-
data-role='close-button'></i>
|
15
|
+
|
19
16
|
</div>
|
20
17
|
|
21
18
|
<\% end %>
|
@@ -1,10 +1,9 @@
|
|
1
1
|
<div class="container-fluid">
|
2
2
|
<div class="row">
|
3
3
|
<div class="col-md-12">
|
4
|
-
<\%= render partial: "new_button" %>
|
5
4
|
<div class="clearfix"></div>
|
6
5
|
<\%= render partial: '<%= list_path_partial %>',
|
7
|
-
locals: {<%=
|
6
|
+
locals: {<%= plural %>: @<%= plural %><%= nest_assignments_operator(true, true) if @nestable %> } \%>
|
8
7
|
</div>
|
9
8
|
</div>
|
10
9
|
</div>
|
@@ -1,6 +1,9 @@
|
|
1
|
-
|
2
|
-
<\%= render partial: 'line', locals: {<%= singular %>: @<%= singular %> <%=
|
1
|
+
<% if !@display_list_after_update %><\%= turbo_stream.replace "<%= singular%>__#{@<%= singular %>.id}" do %>
|
2
|
+
<\%= render partial: 'line', locals: {<%= singular %>: @<%= singular %> <%= nest_assignments_operator(true,true) %> } %>
|
3
|
+
<\% end %><% else %><\%= turbo_stream.replace "<%= plural %>-list" do %>
|
4
|
+
<\%= render partial: '<%= list_path_partial %>', locals: {<%= plural %>: @<%= plural %><%= nest_assignments_operator(true, true) if @nestable %> } \%>
|
3
5
|
<\% end %>
|
6
|
+
<% end %>
|
4
7
|
|
5
8
|
<\%= turbo_stream.replace "flash_notices" do %>
|
6
9
|
<\%= render partial: "layouts/flash_notices" %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
= turbo_frame_tag "<%= singular %>__#{<%= singular %>.id}" do
|
2
2
|
.row{'data-id': <%= singular %>.id, 'data-edit': 'false'}
|
3
|
-
= render partial: "<%= show_path_partial %>", locals: {<%= singular %>: <%= singular %>}
|
3
|
+
= render partial: "<%= show_path_partial %>", locals: {<%= singular %>: <%= singular %> <%= nest_assignments_operator(false, true) %>}
|
4
4
|
|
5
5
|
|
6
6
|
|
@@ -1,11 +1,15 @@
|
|
1
1
|
= turbo_frame_tag "<%= plural %>-list" do
|
2
2
|
.container-fluid.<%= singular %>-table
|
3
3
|
.row
|
4
|
+
.col-md-12
|
5
|
+
<%= '= render partial: "' + (@namespace+"/" if @namespace) + plural + '/new_button", locals: {' + nested_assignments + '}' unless @no_create %>
|
6
|
+
|
7
|
+
.row
|
4
8
|
<%= list_column_headings %>
|
5
9
|
.col
|
6
10
|
%div
|
7
11
|
- if <%= plural %>.empty?
|
8
12
|
None
|
9
13
|
- <%= plural %>.each do |<%= singular %>|
|
10
|
-
= render partial: '<%= line_path_partial %>', locals: {<%= singular %>: <%= singular
|
14
|
+
= render partial: '<%= line_path_partial %>', locals: {<%= singular %>: <%= singular %><%= nested_assignments_with_leading_comma if @nestable %> }
|
11
15
|
<%= @no_paginate ? "" : paginate %>
|
@@ -1,12 +1,12 @@
|
|
1
1
|
- if @<%= singular %>.errors.none?
|
2
2
|
= turbo_stream.replace "<%= plural %>-list" do
|
3
|
-
= render partial: "list", locals: {<%= plural %>: @<%= plural %>}
|
3
|
+
= render partial: "list", locals: {<%= plural %>: @<%= plural %> <%= nest_assignments_operator(true, true) %>}
|
4
4
|
|
5
5
|
= turbo_stream.replace "<%= singular %>-new" do
|
6
6
|
- if @<%= singular %>.errors.none?
|
7
|
-
= render partial: "new_button"
|
7
|
+
= render partial: "new_button", locals: {<%= nest_assignments_operator(true, false) %> }
|
8
8
|
- else
|
9
|
-
= render partial: "new_form", locals: {<%= singular %>: @<%= singular %>}
|
9
|
+
= render partial: "new_form", locals: {<%= singular %>: @<%= singular %> <%= nest_assignments_operator(true, true) %>}
|
10
10
|
|
11
11
|
= turbo_stream.replace "flash_notices" do
|
12
12
|
= render partial: "layouts/flash_notices"
|
@@ -1,2 +1,2 @@
|
|
1
1
|
= turbo_stream.replace "<%=plural%>-list" do
|
2
|
-
= render partial: "list", locals: {<%=plural%>: @<%=plural%>}
|
2
|
+
= render partial: "list", locals: {<%=plural%>: @<%=plural%> <%= nest_assignments_operator(true, true) %>}
|
@@ -17,5 +17,3 @@
|
|
17
17
|
= form_with model: <%= "@" + singular%>, url: <%= path_helper_singular %>(<%= path_arity %>) do |f|
|
18
18
|
= render partial: "form", locals: {:<%= singular %> => <%= "@" + singular%>, f: f}
|
19
19
|
|
20
|
-
%i.fa.fa-times-circle.fa-2x{ 'data-name' => 'close-invoice__#{@invoice.id}', 'data-row-id' => <%= "@" + singular %>.id, 'data-role' => 'close-button'}
|
21
|
-
|
@@ -1,9 +1,8 @@
|
|
1
1
|
.container-fluid
|
2
2
|
.row
|
3
3
|
.col-md-12
|
4
|
-
= render partial: "new_button"
|
5
4
|
.clearfix
|
6
|
-
= render partial: "<%= list_path_partial %>", locals: {<%= plural %>: @<%= plural %>}
|
5
|
+
= render partial: "<%= list_path_partial %>", locals: {<%= plural %>: @<%= plural %> <%= nest_assignments_operator(true, true) %>}
|
7
6
|
|
8
7
|
|
9
8
|
|
@@ -72,7 +72,7 @@ describe "interaction for <%= controller_class_name %>", type: :feature do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
describe "new & create" do
|
75
|
+
<% unless @no_create %> describe "new & create" do
|
76
76
|
it "should create a new <%= singular.titlecase %>" do
|
77
77
|
visit <%= path_helper_plural %>
|
78
78
|
click_link "New <%= singular.titlecase %>"
|
@@ -97,6 +97,12 @@ describe "interaction for <%= controller_class_name %>", type: :feature do
|
|
97
97
|
" find(\"[name='#{singular}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
98
98
|
|
99
99
|
end
|
100
|
+
|
101
|
+
when :enum
|
102
|
+
" list_of_#{col.to_s} = #{singular_class}.defined_enums['#{col.to_s}'].keys \n" +
|
103
|
+
" " + "new_#{col.to_s} = list_of_#{col.to_s}[rand(list_of_#{col.to_s}.length)].to_s \n" +
|
104
|
+
' find("select[name=\'' + singular + '[' + col.to_s + ']\'] option[value=\'#{new_' + col.to_s + '}\']").select_option'
|
105
|
+
|
100
106
|
when :boolean
|
101
107
|
" new_#{col} = rand(2).floor \n" +
|
102
108
|
" find(\"[name='#{singular}[#{col}]'][value='\#{new_" + col.to_s + "}']\").choose"
|
@@ -135,7 +141,7 @@ describe "interaction for <%= controller_class_name %>", type: :feature do
|
|
135
141
|
%>
|
136
142
|
|
137
143
|
end
|
138
|
-
end
|
144
|
+
end<% end %>
|
139
145
|
|
140
146
|
|
141
147
|
describe "edit & update" do
|
@@ -185,6 +191,11 @@ describe "interaction for <%= controller_class_name %>", type: :feature do
|
|
185
191
|
when :time
|
186
192
|
" new_#{col} = Time.current + rand(144).hours \n" +
|
187
193
|
" find(\"[name='#{singular}[#{col}]']\").fill_in(with: new_#{col.to_s })"
|
194
|
+
when :enum
|
195
|
+
" list_of_#{col.to_s} = #{singular_class}.defined_enums['#{col.to_s}'].keys \n" +
|
196
|
+
" " + "new_#{col.to_s} = list_of_#{col.to_s}[rand(list_of_#{col.to_s}.length)].to_s \n" +
|
197
|
+
' find("select[name=\'' + singular + '[' + col.to_s + ']\'] option[value=\'#{new_' + col.to_s + '}\']").select_option'
|
198
|
+
|
188
199
|
else
|
189
200
|
" " + "new_#{col.to_s} = FFaker::Name.name \n" +
|
190
201
|
' find("input[name=\'' + singular + '[' + col.to_s + ']\']").fill_in(with: new_' + col.to_s + ')'
|
@@ -220,17 +231,17 @@ describe "interaction for <%= controller_class_name %>", type: :feature do
|
|
220
231
|
end
|
221
232
|
end
|
222
233
|
|
223
|
-
describe "destroy" do
|
234
|
+
<% unless @no_delete %> describe "destroy" do
|
224
235
|
it "should destroy" do
|
225
236
|
visit <%= path_helper_plural %>
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
find("form[action='<%= namespace_with_dash %>/<%= plural %>/#{<%= singular %>1.id}'] >
|
237
|
+
accept_alert do
|
238
|
+
find("form[action='<%= namespace_with_dash %>/<%= plural %>/#{<%= singular %>1.id}'] > input.delete-<%= singular %>-button").click
|
239
|
+
end
|
240
|
+
# find("form[action='<%= namespace_with_dash %>/<%= plural %>/#{<%= singular %>1.id}'] > input.delete-<%= singular %>-button").click
|
230
241
|
|
231
242
|
expect(page).to_not have_content(<%= singular %>1.<%= @display_class %>)
|
232
243
|
expect(<%= singular_class %>.where(id: <%= singular %>1.id).count).to eq(0)
|
233
244
|
end
|
234
|
-
end
|
245
|
+
end<% end %>
|
235
246
|
end
|
236
247
|
|
data/lib/hot-glue.rb
CHANGED
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.2.
|
4
|
+
version: 0.2.9E
|
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: 2021-
|
11
|
+
date: 2021-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -44,32 +44,18 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.2'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: haml-rails
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '2.0'
|
54
|
-
type: :runtime
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '2.0'
|
61
47
|
- !ruby/object:Gem::Dependency
|
62
48
|
name: turbo-rails
|
63
49
|
requirement: !ruby/object:Gem::Requirement
|
64
50
|
requirements:
|
65
|
-
- - "
|
51
|
+
- - ">"
|
66
52
|
- !ruby/object:Gem::Version
|
67
53
|
version: '0.5'
|
68
54
|
type: :runtime
|
69
55
|
prerelease: false
|
70
56
|
version_requirements: !ruby/object:Gem::Requirement
|
71
57
|
requirements:
|
72
|
-
- - "
|
58
|
+
- - ">"
|
73
59
|
- !ruby/object:Gem::Version
|
74
60
|
version: '0.5'
|
75
61
|
- !ruby/object:Gem::Dependency
|
@@ -177,24 +163,24 @@ licenses:
|
|
177
163
|
- Nonstandard
|
178
164
|
metadata:
|
179
165
|
source_code_uri: https://github.com/jasonfb/hot-glue
|
180
|
-
documentation_uri: https://
|
181
|
-
homepage_uri: https://
|
166
|
+
documentation_uri: https://jasonfleetwoodboldt.com/hot-glue/
|
167
|
+
homepage_uri: https://github.com/jasonfb/hot-glue
|
182
168
|
post_install_message: |
|
183
169
|
---------------------------------------------
|
184
170
|
Welcome to Hot Glue - A Scaffold Building Companion for Hotwire + Turbo-Rails
|
185
171
|
|
186
172
|
rails generate hot_glue:scaffold Thing
|
187
173
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
174
|
+
* Build plug-and-play scaffolding mixing generated ERB or HAML with the power of Hotwire and Turbo-Rails
|
175
|
+
* Everything edits-in-place (unless you use --big-edit, then it won't)
|
176
|
+
* Automatically Reads Your Models (make them before building your scaffolding!)
|
177
|
+
* Excellent for CREATE-READ-UPDATE-DELETE (CRUD), lists with pagination (coming soon: searching & sorting)
|
178
|
+
* Great for prototyping, but you should learn Rails fundamentals first.
|
179
|
+
* 'Packaged' with Devise, Kaminari, Rspec, FontAwesome
|
180
|
+
* Create system specs automatically along with the generated code.
|
181
|
+
* Nest your routes model-by-model for built-in poor man's authentication.
|
182
|
+
* Throw the scaffolding away when your app is ready to graduate to its next phase.
|
183
|
+
* docs at https://github.com/jasonfb/hot-glue
|
198
184
|
---------------------------------------------
|
199
185
|
rdoc_options: []
|
200
186
|
require_paths:
|
@@ -206,11 +192,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
206
192
|
version: '0'
|
207
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
194
|
requirements:
|
209
|
-
- - "
|
195
|
+
- - ">"
|
210
196
|
- !ruby/object:Gem::Version
|
211
|
-
version:
|
197
|
+
version: 1.3.1
|
212
198
|
requirements: []
|
213
|
-
rubygems_version: 3.1.
|
199
|
+
rubygems_version: 3.1.6
|
214
200
|
signing_key:
|
215
201
|
specification_version: 4
|
216
202
|
summary: A gem build scaffolding.
|