hot-glue 0.6.19 → 0.6.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -321,6 +321,166 @@ TitleCase class name of the thing you want to build a scaffolding for.
321
321
 
322
322
  (note: Your `Thing` object must `belong_to` an authenticated `User` or alternatively you must create a Gd controller, see below.)
323
323
 
324
+
325
+ ## FLAGS (Options with no values)
326
+ These options (flags) also uses `--` syntax but do not take any values. (Notice no equal sign.) Everything is assumed (default) to be false unless specified.
327
+
328
+
329
+ ### `--stacked-downnesting`
330
+
331
+ 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.
332
+
333
+
334
+
335
+ ### `--god` or `--gd`
336
+
337
+ Use this flag to create controllers with no root authentication. You can still use an auth_identifier, which can be useful for a meta-leval authentication to the controller.
338
+
339
+ For example, FOR ADMIN CONTROLLERS ONLY, supply a auth_identifier and use `--god` flag.
340
+
341
+ In Gd mode, the objects are loaded directly from the base class (these controllers have full access)
342
+ ```
343
+ def load_thing
344
+ @thing = Thing.find(params[:id])
345
+ end
346
+
347
+ ```
348
+
349
+ ### `--button-icons` (default is no icons)
350
+ You can specify this either as builder flag or as a config setting (in `config/hot_glue.yml`)
351
+ Use `font-awesome` for Font Awesome or `none` for no icons.
352
+
353
+
354
+ ### `--specs-only`
355
+
356
+ Produces ONLY the controller spec file, nothing else.
357
+
358
+
359
+ ### `--no-specs`
360
+
361
+ Produces all the files except the spec file.
362
+
363
+
364
+ ### `--no-paginate` (default: false)
365
+
366
+ Omits pagination. (All list views have pagination by default.)
367
+
368
+ ### `--paginate-per-page-selector` (default: false)
369
+
370
+ Show a small drop-down below the list to let the user choose 10, 25, or 100 results per page.
371
+
372
+
373
+ ### `--no-list`
374
+
375
+ Omits list action. Only makes sense to use this if want to create a view where you only want the create button or to navigate to the update screen alternative ways. (The new/create still appears, as well the edit, update & destroy actions are still created even though there is no natural way to navigate to them.)
376
+
377
+
378
+
379
+ ### `--no-create`
380
+
381
+ Omits new & create actions.
382
+
383
+ ### `--no-delete`
384
+
385
+ Omits delete button & destroy action.
386
+
387
+ ### `--no-controller`
388
+
389
+ Omits controller.
390
+
391
+ ### `--no-list`
392
+
393
+ Omits list views.
394
+
395
+ `--new-button-position` (above, below; default: above)
396
+ Show the new button above or below the list.
397
+
398
+ `--downnest-shows-headings` (default: false)
399
+ Show headings above downnested portals.
400
+
401
+
402
+ ### `--big-edit`
403
+
404
+ If you do not want inline editing of your list items but instead want to fallback to full-page style behavior for your edit views, use `--big-edit`.
405
+
406
+ The user will be taken to a full-screen edit page instead of an edit-in-place interaction.
407
+
408
+ When using `--big-edit`, any downnested portals will be displayed on the edit page instead of on the list page.
409
+
410
+ Big edit makes all edit and magic button operations happen using `'data-turbo': false`, fully reloading the page and submitting HTML requests instead of TURBO_STREAM requests.
411
+
412
+ Likewise, the controller's `update` action always redirects instead of using Turbo.
413
+
414
+
415
+ ### `--display-list-after-update`
416
+
417
+ After an update-in-place normally only the edit view is swapped out for the show view of the record you just edited.
418
+
419
+ 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).
420
+
421
+ 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.
422
+
423
+ ### `--with-turbo-streams`
424
+
425
+ 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.
426
+
427
+ **_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.
428
+
429
+ This happens using two interconnected mechanisms:
430
+
431
+ 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
432
+
433
+ 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.
434
+
435
+ 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.
436
+
437
+
438
+ ### `--no-list-label`
439
+ Omits list LABEL itself above the list. (Do not confuse with the list heading which contains the field labels.)
440
+
441
+ Note that list labels may be automatically omitted on downnested scaffolds.
442
+
443
+
444
+ ### `--no-list-heading`
445
+
446
+ Omits the heading of column names that appears above the 1st row of data.
447
+
448
+ ### `--include-object-names`
449
+
450
+ When you are "Editing X" we specify that X is a ___ (author, book, room, etc)
451
+
452
+ e.g. "Editing author Edgar Allan Poe" vs "Editing Edgar Allan Poe"
453
+
454
+ Can also be specified globally in `config/hot_glue.yml`
455
+
456
+ ## Nav Templates and `--no-nav-menu`
457
+ At the namespace level, you can have a file called `_nav.html.erb` to create tabbed bootstrap nav
458
+
459
+ To create the file for the first time (at each namespace), start by running
460
+ ```
461
+ bin/rails generate hot_glue:nav_template --namespace=xyz
462
+ ```
463
+
464
+ This will append the file `_nav.html.erb` to the views folder at `views/xyz`. To begin, this file contains only the following:
465
+
466
+ ```
467
+ <ul class='nav nav-tabs'>
468
+ </ul>
469
+ ```
470
+
471
+ Once the file is present, any further builds in this namespace will:
472
+
473
+ 1) Append to this `_nav.html.erb` file, adding a tab for the new built scaffold
474
+ 2) On the list view of the scaffold being built, it will include a render to the _nav partial, passing the name of the currently-viewed thing as the local variable `nav` (this is how the nav template knows which tab to make active).
475
+ ```
476
+ <%= render partial: "owner/nav", locals: {nav: "things"} %>
477
+ ```
478
+ (In this example `owner/` is the namespace and `things` is the name of the scaffold being built)
479
+
480
+ To suppress this behavior, add `--no-nav-menu` to the build command and the _nav template will not be touched.
481
+
482
+
483
+
324
484
  ## Options With Arguments
325
485
 
326
486
  All options begin with two dashes (`--`) and a followed by an `=` and a value
@@ -348,7 +508,6 @@ end
348
508
 
349
509
  ```
350
510
 
351
-
352
511
  ### `--nested=`
353
512
 
354
513
  This object is nested within another tree of objects, and there is a nested route in your `routes.rb` file with the specified parent controllers above this controller. When specifying the parent(s), be sure to use **singular case**.
@@ -771,8 +930,7 @@ Hot Glue gives you automatic field level access control if you create `*_able?`
771
930
  The `*_able?` method should return true or false depending on whether or not the field can be edited. No distinction is made between the `new` and `edit` contexts. You may check if the record is new using `new_record?`.
772
931
 
773
932
 
774
- **The `*_able?` method is used by Hot Glue only on the new and edit actions. You must incorporate it into the policy's `update?` method as in the example, or else no guard will check prevent the user doesn't pass a value to input it anyway.**
775
-
933
+ **The `*_able?` method is used by Hot Glue only on the new and edit actions and also affects the strong parameters, so you no longer need to incorporate it into your policy's `update?` method
776
934
 
777
935
  Add one `*_able?` method to the policy for each field you want to allow field-level access control.
778
936
 
@@ -781,12 +939,8 @@ Replace `*` with the name of the field you want under access control. Remember t
781
939
  When the method returns true, the field will be displayed to the user (and allowed) for editing.
782
940
  When the method returns false, the field will be displayed as read-only (viewable) to the user.
783
941
 
784
- Important: These special fields determine *only* display behavior (new and edit), not create and update.
785
-
786
- For create & update field-level access control, you must also implement the `update?` method on the Policy. Notice how in the example policy below, the `update?` method uses the `name_able?` method when it is checking if the name field can be updated, tying the feature together.
787
-
788
942
  You can set Pundit to be enabled globally on the whole project for every build in `config/hot_glue.yml` (then you can leave off the `--pundit` flag from the scaffold command)
789
- `:pundit_default:` (all builds in that project will use Pundit)
943
+ `:pundit:` (all builds in that project will use Pundit)
790
944
 
791
945
 
792
946
  Here's an example `ThingPolicy` that would allow **editing the name field** only if:
@@ -808,14 +962,11 @@ class ThingPolicy < ApplicationPolicy
808
962
  end
809
963
 
810
964
  def update?
811
- if !@user.is_admin?
812
- return false
813
- elsif record.name_changed? && !name_able?
814
- record.errors.add(:name, "cannot be changed.")
815
- return false
816
- else
817
- return true
818
- end
965
+ !@user.is_admin?
966
+ end
967
+
968
+ def edit?
969
+ !@user.is_admin?
819
970
  end
820
971
 
821
972
  class Scope < Scope
@@ -828,12 +979,11 @@ class ThingPolicy < ApplicationPolicy
828
979
  end
829
980
  ```
830
981
 
831
-
832
982
  Because Hot Glue detects the `*_able?` methods at build time, if you add them to your policy, you will have to rebuild your scaffold.
833
983
 
834
984
 
835
- ### `--pundit-policy-override`
836
- if you use the flag `--pundit-policy-override` your controller operations will bypass the invisible (pundit provided) access control and use the pundit policy you specify.
985
+ ### `--pundit-policy-override=`
986
+ if you pass a custom pundit class to `--pundit-policy-override=` your controller operations will bypass the invisible (pundit provided) access control and use the pundit policy you specify.
837
987
 
838
988
  example
839
989
 
@@ -849,6 +999,8 @@ If provided, the output code looks something like (in this example, showing the
849
999
  ```
850
1000
 
851
1001
 
1002
+
1003
+
852
1004
  ### `--show-only=`
853
1005
  (separate field names by COMMA)
854
1006
 
@@ -860,7 +1012,7 @@ IMPORTANT: By default, all fields that begin with an underscore (`_`) are automa
860
1012
  This is for fields you want globally non-editable by users in your app. For example, a counter cache or other field set only by a backend mechanism.
861
1013
 
862
1014
 
863
- ### `--update-show-only`
1015
+ ### `--update-show-only=`
864
1016
  (separate field names by COMMA)
865
1017
 
866
1018
  • Make this field appear as viewable only for the edit action (and not allowed in the update action).
@@ -909,18 +1061,19 @@ Remember, if there's a corresponding `*_able?` method on the policy, it will be
909
1061
 
910
1062
  As shown in the method `name_able?` of the example ThingPolicy above, if this field on your policy returns true, the field will be editable. If it returns false, the field will be viewable (read-only).
911
1063
 
912
-
913
- ### `--hidden`
914
-
1064
+ ### `--hidden=` (affects both create + update actions)
1065
+ ### `--create-hidden=`
1066
+ ### `--update-hidden=`
1067
+ TODO: RENAME ME TO INVISIBLE
915
1068
  Separate list of fields.
916
1069
 
917
- These fields will be hidden from the form but will exist as hidden_field, and so the update will still work.
1070
+ These fields will exist on the create or update form exist as hidden_field, and so the update will still work._
918
1071
 
919
1072
 
920
1073
  EXAMPLE:
921
1074
 
922
1075
  ```
923
- bin/rails generate hot_glue:scaffold Wrapper --namespace='account_dashboard' --no-nav-menu --big-edit --smart-layout --stimmify --hidden=raw_source
1076
+ bin/rails generate hot_glue:scaffold Wrapper --namespace='account_dashboard' --no-nav-menu --big-edit --smart-layout --stimmify --invisible=raw_source
924
1077
  ```
925
1078
 
926
1079
  In the `wrappers` folder, I am using a special sticky partial `_edit_within_form.html.erb`, which contains code preserved from build-to-build and included in the form:
@@ -992,7 +1145,77 @@ Notice we are also using `--stimmify` to decorate the form with a Stimulus contr
992
1145
 
993
1146
  The code above uses Code Mirror to act as a code editor, which requires pulling the value off the hidden form element (putting it into the code mirror interface) and pushing it back into the hidden form element when the Submit button is clicked.
994
1147
 
1148
+ ### `--invisible=`
1149
+ ### `--create-invisible=`
1150
+ ### `--update-invisible=`
1151
+ (two lists are maintained: create and update. any fields on the unnamed invisible list will be invisible on both create and update actions)
1152
+
1153
+ If a field is on the invisible list, the policy will be checked for a `_able?` method.
1154
+ If this method returns true, displayed like a normal editable field.
1155
+
1156
+ If the policy doesn't allow editing, this field will be made invisible: completely removed from the form.
995
1157
 
1158
+ Like show only, these will check for `*_able?` methods on the object or Policy and will only display the field if the method returns true.
1159
+
1160
+ It will also block the field from being updated on the backend, so don't use this if you want to create a hidden_field tag but still allow the controller to update it. (For that, see `--hidden=`.)
1161
+
1162
+
1163
+ Like show-only, note special behavior with pundit.
1164
+
1165
+ A field can be marked invisible and show-only, in which case the invisible rule take prescedence when the access control is denied (field removed from form) but th show-only rule takes prescedance when the access control is granted,
1166
+
1167
+ Hidden can be used with invisible. In this case, the access control will be applied to the field. When editable, the hidden field output will be used.
1168
+
1169
+ Must be used with Pundit. Without pundit, see other alternatives: hidden fields, show only fields, or just removing the field completely by using the exclude list or leaving it off the include list.
1170
+
1171
+ | | | Pundit | | |
1172
+ |----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|---|
1173
+ | fields not on any of these other lists | Included as editable on both the create + update actions or as viewable if Policy access control returns false | Without pundit, everything is editable. With pundit, the Policy is checked for an `_able?` method for each field at build time. When this method returns false, the field is viewable. | | |
1174
+ | Show only | Viewable only (non-editable) on both create + edit/update overriding whatever Policy returns. | Without pundit, this field is viewable only. Overrides whatever policy returns. | | |
1175
+ | Update Show only | Viewable only on the update screen or if Pundit doesn't allow editing | Same as above but apply only to the update screen. | | |
1176
+ | Invisible | Displayed in the HTML output and received by the controller for create or update action but shown as a hidden_field on the HTML, invisible to the user. You should use this if you want to construct your own form input or set the value via Javascript | Cannot be used without Pundit. With pundit, fields editable via the policy are editable on the screen (unless they are also show-only, in which case they are visible) and non-editable via the policy are made invisible (completely removed) from the screen. | | |
1177
+ | Hidden | Not displayed or updatable if the field respond false to _able? or the Policy doesn't allow. | Unrelated to pundit Policy | | |
1178
+ | | | | | |
1179
+
1180
+
1181
+ Pundit calls the policy for every action, including the index action. In these cases it passes an association instead of a single record.
1182
+
1183
+ Normally, field level access control that applies for show only and invisible is affects each record, in the list view, new page, or edit page.
1184
+
1185
+ For that reason, your `_able?` methods may check the individual records, except in the case of the `index` action for which the pundit policy has no individual record.
1186
+
1187
+ For these special cases, you might want to hide the entire column itself when the `_able?` return false on the association call (not in the context any of any record).
1188
+
1189
+ You'd want to do this for a global switch, unrelated to the record, to show or hide the column itself. When using invisible fields, the column headings are check against the policy's `_able?` fields, too, but since this called on the list, the entire set of objects being returned by the list is passed to the policy. (For example `policy(@things)`)
1190
+
1191
+ This makes it impossible to make your access control depend solely on the record itself, so can be used only for context-based access control that is applied to the column headings.
1192
+
1193
+
1194
+ In a case like this, you'll want the `_able?` method on the policy to know if the object is a record or many records.
1195
+
1196
+ ```
1197
+ class ThingPolicy < ApplicationPolicy
1198
+ attr_reader :user, :thing
1199
+
1200
+ def initialize(user, thing)
1201
+ @user = user
1202
+ @thing = thing
1203
+ end
1204
+
1205
+ def ccc_able?
1206
+ if thing.is_a?(Thing) # a thing is not a Thing when it is an active relation of many things
1207
+ !!thing.bbb # show or hide ccc based on whether or not bbb is true
1208
+ else
1209
+ current_user.is_admin? # show or hide the column heading for ccc based on whether or not the current user is an admin
1210
+ end
1211
+ end
1212
+ # more policy method here ...
1213
+ end
1214
+ ```
1215
+ Here, for all CRUD actions, the object is a thing, and so the editablility of ccc is dependent on bbb being true.
1216
+ If thing is not a Thing, then it is active relation (so this applies to the column headings) and we show it only to admins.
1217
+
1218
+ Remember, since the `_able?` methods are not otherwise called during Pundit's index cycle, this applies only to the list column headings and has no bearing on create, update, read, delete for which the access control can be anything you want that is available to the Poilcy.
996
1219
 
997
1220
 
998
1221
 
@@ -1014,7 +1237,7 @@ and also fix any Rails apps created since October 2021 by fixing the Gemfile. De
1014
1237
  https://stackoverflow.com/questions/70671324/new-rails-7-turbo-app-doesnt-show-the-data-turbo-confirm-alert-messages-dont-f
1015
1238
 
1016
1239
 
1017
- ### `--magic-buttons`
1240
+ ### `--magic-buttons=`
1018
1241
  If you pass a list of magic buttons (separated by commas), they will appear in the button area on your list.
1019
1242
 
1020
1243
  It will be assumed there will be corresponding bang methods on your models.
@@ -1035,8 +1258,13 @@ Finally, you can raise an ActiveRecord error which will also get passed to the u
1035
1258
 
1036
1259
  For more information see [Example 6 in the Tutorial](https://school.jfbcodes.com/8188)
1037
1260
 
1261
+ You can also define methods on your model that have the same name as the button with `_able?` at the end.
1262
+ (Prior to v0.6.20, these methods expected names with `able?` but no underscore.)
1263
+
1264
+ The button will be display as disabled if the method returns false.
1265
+
1038
1266
 
1039
- ### `--downnest`
1267
+ ### `--downnest=`
1040
1268
 
1041
1269
  Automatically create subviews down your object tree. This should be the name of a has_many relationship based from the current object.
1042
1270
  You will need to build scaffolding with the same name for the related object as well. 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.
@@ -1048,11 +1276,6 @@ Can now be created with more space (wider) by adding a `+` to the end of the dow
1048
1276
 
1049
1277
  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
1050
1278
 
1051
- ### `--stacked-downnesting`
1052
-
1053
- 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.
1054
-
1055
-
1056
1279
 
1057
1280
  ### `--record-scope=`
1058
1281
 
@@ -1071,113 +1294,9 @@ scope :is_open, -> {where(state == 'open')}
1071
1294
 
1072
1295
  Now all records displayed through the generated controller
1073
1296
 
1074
- ## FLAGS (Options with no values)
1075
- These options (flags) also uses `--` syntax but do not take any values. Everything is assumed (default) to be false unless specified.
1076
-
1077
- ### `--god` or `--gd`
1078
-
1079
- Use this flag to create controllers with no root authentication. You can still use an auth_identifier, which can be useful for a meta-leval authentication to the controller.
1080
-
1081
- For example, FOR ADMIN CONTROLLERS ONLY, supply a auth_identifier and use `--god` flag.
1082
-
1083
- In Gd mode, the objects are loaded directly from the base class (these controllers have full access)
1084
- ```
1085
- def load_thing
1086
- @thing = Thing.find(params[:id])
1087
- end
1088
-
1089
- ```
1090
-
1091
- ### `--button-icons` (default is no icons)
1092
- You can specify this either as builder flag or as a config setting (in `config/hot_glue.yml`)
1093
- Use `font-awesome` for Font Awesome or `none` for no icons.
1094
-
1095
-
1096
- ### `--specs-only`
1097
-
1098
- Produces ONLY the controller spec file, nothing else.
1099
-
1100
-
1101
- ### `--no-specs`
1102
-
1103
- Produces all the files except the spec file.
1104
-
1105
-
1106
- ### `--no-paginate` (default: false)
1107
-
1108
- Omits pagination. (All list views have pagination by default.)
1109
-
1110
- ### `--paginate-per-page-selector` (default: false)
1111
-
1112
- Show a small drop-down below the list to let the user choose 10, 25, or 100 results per page.
1113
-
1114
-
1115
- ### `--no-list`
1116
-
1117
- Omits list action. Only makes sense to use this if want to create a view where you only want the create button or to navigate to the update screen alternative ways. (The new/create still appears, as well the edit, update & destroy actions are still created even though there is no natural way to navigate to them.)
1118
-
1119
-
1120
-
1121
- ### `--no-create`
1122
-
1123
- Omits new & create actions.
1124
-
1125
- ### `--no-delete`
1126
-
1127
- Omits delete button & destroy action.
1128
-
1129
- ### `--no-controller`
1130
-
1131
- Omits controller.
1132
-
1133
- ### `--no-list`
1134
-
1135
- Omits list views.
1136
-
1137
- `--new-button-position` (above, below; default: above)
1138
- Show the new button above or below the list.
1139
-
1140
- `--downnest-shows-headings` (default: false)
1141
- Show headings above downnested portals.
1142
-
1143
-
1144
- ### `--big-edit`
1145
-
1146
- If you do not want inline editing of your list items but instead want to fallback to full-page style behavior for your edit views, use `--big-edit`.
1147
-
1148
- The user will be taken to a full-screen edit page instead of an edit-in-place interaction.
1149
-
1150
- When using `--big-edit`, any downnested portals will be displayed on the edit page instead of on the list page.
1151
-
1152
- Big edit makes all edit and magic button operations happen using `'data-turbo': false`, fully reloading the page and submitting HTML requests instead of TURBO_STREAM requests.
1153
-
1154
- Likewise, the controller's `update` action always redirects instead of using Turbo.
1155
-
1156
-
1157
- ### `--display-list-after-update`
1158
-
1159
- After an update-in-place normally only the edit view is swapped out for the show view of the record you just edited.
1160
-
1161
- 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).
1162
-
1163
- 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.
1164
-
1165
- ### `--with-turbo-streams`
1166
-
1167
- 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.
1168
-
1169
- **_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.
1170
-
1171
- This happens using two interconnected mechanisms:
1172
-
1173
- 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
1174
-
1175
- 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.
1176
-
1177
- 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.
1178
1297
 
1179
1298
 
1180
- ### `--related-sets`
1299
+ ### `--related-sets=`
1181
1300
 
1182
1301
  Used to show a checkbox set of related records. The relationship should be a `has_and_belongs_to_many` or a `has_many through:` from the object being built.
1183
1302
 
@@ -1196,58 +1315,43 @@ Note this leaves open a privileged escalation attack (a security vulnerability).
1196
1315
  To fix this, you'll need to use Pundit with special syntax designed for this purpose. Please see [Example #17 in the Hot Glue Tutorial](https://school.jfbcodes.com/8188)
1197
1316
 
1198
1317
 
1199
- ## "Thing" Label
1200
-
1201
- Note that on a per model basis, you can also globally omit the label or set a unique label value using
1202
- `@@table_label_singular` and `@@table_label_plural` on your model objects.
1203
-
1204
- You have three options to specify labels explicitly with a string, and 1 option to specify a global name for which the words "Delete ___" and "New ___" will be added.
1205
-
1206
- If no `--label` is specified, it will be inferred to be the Capitalized version of the name of the thing you are building, with spaces for two or more words.
1207
-
1208
- ### `--label`
1318
+ ### `--label=`
1209
1319
 
1210
1320
  The general name of the thing, will be applied as "New ___" for the new button & form. Will be *pluralized* for list label heading, so if the word has a non-standard pluralization, be sure to specify it in `config/inflictions.rb`
1211
1321
 
1212
1322
  If you specify anything explicitly, it will be used.
1213
1323
  If not, a specification that exists as `@@tabel_label_singular` from the Model will be used.
1214
- If this does not exist, the Titleized (capitalized) version of the model name.
1324
+ If this does not exist, the Titleized (capitalized) version of the model name.
1215
1325
 
1216
- ### `--list-label-heading`
1326
+ ### `--list-label-heading=`
1217
1327
  The plural of the list of things at the top of the list.
1218
1328
  If not, a specification that exists as `@@tabel_label_plural` from the Model will be used.
1219
1329
  If this does not exist, the UPCASE (all-uppercase) version of the model name.
1220
1330
 
1221
- ### `--new-button-label`
1222
- The button on the list that the user clicks onto to create a new record.
1223
- (Follows same rules described in the `--label` option but with the word "New" prepended.)
1331
+ ### `--new-button-label=`
1332
+ Overrides the button on the list that the user clicks onto to create a new record.
1333
+ (Default is to follow the same rules described in the `--label` option but with the word "New" prepended.)
1224
1334
 
1225
- ### `--new-form-heading`
1335
+ ### `--new-form-heading=`
1226
1336
  The text at the top of the new form that appears when the new input entry is displayed.
1227
- (Follows same rules described in the `--label` option but with the word "New" prepended.)
1228
-
1229
- ### `--no-list-label`
1230
- Omits list LABEL itself above the list. (Do not confuse with the list heading which contains the field labels.)
1231
-
1232
- Note that list labels may be automatically omitted on downnested scaffolds.
1233
-
1337
+ (Default follows the same rules described in the `--label` option but with the word "New" prepended.)
1234
1338
 
1235
1339
  ## Field Labels
1236
1340
 
1237
- ### `--form-labels-position` (default: `after`; options are **before**, **after**, and **omit**)
1341
+ ### `--form-labels-position=` (default: `after`; options are **before**, **after**, and **omit**)
1238
1342
  By default form labels appear after the form inputs. To make them appear before or omit them, use this flag.
1239
1343
 
1240
1344
  See also `--form-placeholder-labels` to use placeolder labels.
1241
1345
 
1242
1346
 
1243
- ### `--form-placeholder-labels` (default: false)
1347
+ ### `--form-placeholder-labels=` (default: false)
1244
1348
 
1245
1349
  When set to true, fields, numbers, and text areas will have placeholder labels.
1246
1350
  Will not apply to dates, times, datetimes, dropdowns (enums + foreign keys), or booleans.
1247
1351
 
1248
1352
  See also setting `--form-labels-position` to control position or omit normal labels.
1249
1353
 
1250
- ### `--inline-list-labels` (before, after, omit; default: omit)
1354
+ ### `--inline-list-labels=` (before, after, omit; default: omit)
1251
1355
 
1252
1356
  Determines if field label will appear on the LIST VIEW. Note that because Hot Glue has no separate show route or page, this affects the `_show` template which is rendered as a partial from the LIST view.
1253
1357
 
@@ -1256,36 +1360,36 @@ Because the labels are already in the heading, this is `omit` by default. (Use w
1256
1360
  Use `before` to make the labels come before or `after` to make them come after. See Version 0.5.1 release notes for an example.
1257
1361
 
1258
1362
 
1259
- ### `--no-list-heading`
1363
+ ### Code insertions
1364
+ Insert some code into the `new`, `create` or `update` action actions.
1260
1365
 
1261
- Omits the heading of column names that appears above the 1st row of data.
1366
+ Wrapped in quotation marks when specified in the command line, and use semicolons to separate multiple lines of code.
1367
+ (Notice the funky indentation of the lines in the generated code. Adjust you input to get the indentation correct.)
1262
1368
 
1263
- ### `--include-object-names`
1264
1369
 
1265
- When you are "Editing X" we specify that X is a ___ (author, book, room, etc)
1266
1370
 
1267
- e.g. "Editing author Edgar Allan Poe" vs "Editing Edgar Allan Poe"
1371
+ #### `--code-before-create=`
1268
1372
 
1269
- Can also be specified globally in `config/hot_glue.yml`
1373
+ called _after authorization_ but _before saving the new record_
1374
+ (which creates the record, or fails validation).
1375
+ Here you can do things like set default values, or modify the params before the record is saved.
1270
1376
 
1377
+ #### `--code-after-create=`
1378
+ is called after the record is saved (and thus has an id in the case of the create action).
1271
1379
 
1272
- ### Code insertions
1380
+ #### `--code-before-update=`
1381
+ is called in the `update` action _before_ it is saved.
1382
+ `
1383
+ #### `--code-after-update=`
1384
+ is called in the `update` action _after_ it is saved.
1273
1385
 
1274
- `--code-before-create`
1275
- `--code-after-create`
1276
- `--code-before-update`
1277
- `--code-after-update`
1386
+ #### `--code-after-new=`
1387
+ is called in the `new` after the .new() call
1278
1388
 
1279
- Insert some code into the `create` action or `update` actions.
1280
- The **before code** is called _after authorization_ but _before saving_ (which creates the record, or fails validation).
1281
- The **after create** code is called after the record is saved (and thus has an id in the case of the create action).
1282
- Both should be wrapped in quotation marks when specified in the command line, and use semicolons to separate multiple lines of code.
1283
- (Notice the funky indentation of the lines in the generated code. Adjust you input to get the indentation correct.)
1284
1389
 
1285
1390
 
1286
- ## Searching
1287
1391
 
1288
- ### `--search` (options: simple, set, false predicate, default: false)
1392
+ ### `--search=` (options: simple, set, false predicate, default: false)
1289
1393
 
1290
1394
 
1291
1395
  #### Set Search
@@ -1336,24 +1440,12 @@ Here's how you would add a search interface to Example #1 in the [Hot Glue Tutor
1336
1440
  bin/rails generate Book --include=name,author_id --search=set --search-fields=name,author_id
1337
1441
  ```
1338
1442
 
1339
-
1340
-
1341
-
1342
-
1343
- #### Predicate
1443
+ #### Predicate Search
1344
1444
  NOT IMPLEMENTED YET
1345
1445
  TODO: implement me
1346
1446
 
1347
1447
 
1348
-
1349
-
1350
-
1351
-
1352
-
1353
-
1354
- ## Special Features
1355
-
1356
- ### `--attachments`
1448
+ ### `--attachments=`
1357
1449
 
1358
1450
  #### ActiveStorage Quick Setup
1359
1451
  (For complete docs, refer to https://guides.rubyonrails.org/active_storage_overview.html)
@@ -1397,7 +1489,7 @@ If it finds one, it will render thumbnails from the attachment variant `thumb`.
1397
1489
 
1398
1490
  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.
1399
1491
 
1400
- #### `--attachments` Long form syntax with 1 parameter
1492
+ #### `--attachments=` Long form syntax with 1 parameter
1401
1493
 
1402
1494
  **--attachments='_attachment name_{_variant name_}'**
1403
1495
 
@@ -1417,7 +1509,7 @@ end
1417
1509
  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.
1418
1510
 
1419
1511
 
1420
- #### `--attachments` Long form syntax with 1st and 2nd parameters
1512
+ #### `--attachments=` Long form syntax with 1st and 2nd parameters
1421
1513
 
1422
1514
  **--attachments='_attachment name_{_variant name_|_field for saving original filename_}'**
1423
1515
 
@@ -1431,7 +1523,7 @@ Note that the `orig_filename` is not part of the inputted parameters, it simply
1431
1523
 
1432
1524
  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.
1433
1525
 
1434
- #### `--attachments` Long form syntax with 1st, 2nd, and 3rd parameters
1526
+ #### `--attachments=` Long form syntax with 1st, 2nd, and 3rd parameters
1435
1527
 
1436
1528
  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.
1437
1529
 
@@ -1443,7 +1535,7 @@ If you leave the 2nd parameter blank when using the 3rd parameter, it will defau
1443
1535
 
1444
1536
  `--attachments='avatar{thumbnail||direct}'`
1445
1537
 
1446
- #### `--attachments` Long form syntax with 4 parameters
1538
+ #### `--attachments=` Long form syntax with 4 parameters
1447
1539
 
1448
1540
  The final (4th) parameter should be `dropzone` to enable dropzone support for this attachment.
1449
1541
 
@@ -1647,32 +1739,18 @@ Always:
1647
1739
 
1648
1740
  Don't include this last line in your factory code.
1649
1741
 
1650
- ## Nav Templates and `--no-nav-menu`
1651
- At the namespace level, you can have a file called `_nav.html.erb` to create tabbed bootstrap nav
1652
-
1653
- To create the file for the first time (at each namespace), start by running
1654
- ```
1655
- bin/rails generate hot_glue:nav_template --namespace=xyz
1656
- ```
1657
1742
 
1658
- This will append the file `_nav.html.erb` to the views folder at `views/xyz`. To begin, this file contains only the following:
1743
+ # SPECIAL FEATURES
1659
1744
 
1660
- ```
1661
- <ul class='nav nav-tabs'>
1662
- </ul>
1663
- ```
1664
1745
 
1665
- Once the file is present, any further builds in this namespace will:
1746
+ ## "Thing" Label
1666
1747
 
1667
- 1) Append to this `_nav.html.erb` file, adding a tab for the new built scaffold
1668
- 2) On the list view of the scaffold being built, it will include a render to the _nav partial, passing the name of the currently-viewed thing as the local variable `nav` (this is how the nav template knows which tab to make active).
1669
- ```
1670
- <%= render partial: "owner/nav", locals: {nav: "things"} %>
1671
- ```
1672
- (In this example `owner/` is the namespace and `things` is the name of the scaffold being built)
1748
+ Note that on a per model basis, you can also globally omit the label or set a unique label value using
1749
+ `@@table_label_singular` and `@@table_label_plural` on your model objects.
1673
1750
 
1674
- To suppress this behavior, add `--no-nav-menu` to the build command and the _nav template will not be touched.
1751
+ You have three options to specify labels explicitly with a string, and 1 option to specify a global name for which the words "Delete ___" and "New ___" will be added.
1675
1752
 
1753
+ If no `--label` is specified, it will be inferred to be the Capitalized version of the name of the thing you are building, with spaces for two or more words.
1676
1754
 
1677
1755
 
1678
1756
  ## Automatic Base Controller
@@ -1715,7 +1793,7 @@ Child portals have the headings omitted automatically (there is a heading identi
1715
1793
 
1716
1794
 
1717
1795
 
1718
- # Note about enums
1796
+ ## Note about enums
1719
1797
 
1720
1798
  The Rails 7 enum implementation for Postgres is very slick but has a counter-intuitive facet.
1721
1799
 
@@ -1760,7 +1838,7 @@ Now, your labels will show up on the front-end as defined in the `_labels` ("Is
1760
1838
 
1761
1839
  You can modify an enum so that instead of a drop down list, it displays a partial view that you must build. See the [v0.5.23 Release notes](https://github.com/hot-glue-for-rails/hot-glue#2023-10-01---v0523) for details.
1762
1840
 
1763
- ### Validation Magic
1841
+ ## Validation Magic
1764
1842
 
1765
1843
  Use ActiveRecord validations or hooks to validate your data. Hot Glue will automatically display the errors in the UI.
1766
1844
 
@@ -1778,7 +1856,7 @@ end
1778
1856
 
1779
1857
  ```
1780
1858
 
1781
- ### Typeahead Foreign Keys
1859
+ ## Typeahead Foreign Keys
1782
1860
 
1783
1861
  Let's go back to the first Books & Authors example.
1784
1862
  assuming you have created
@@ -1876,7 +1954,7 @@ This means that to find users within the search, the essential piece of informat
1876
1954
  --
1877
1955
 
1878
1956
 
1879
- ### TinyMCE
1957
+ ## TinyMCE
1880
1958
  1. `bundle add tinymce-rails` to add it to your Gemfile
1881
1959
 
1882
1960
  2. Add this inside of your `<head>` tag (at the bottom is fine)
@@ -1954,6 +2032,41 @@ These automatic pickups for partials are detected at build time. This means that
1954
2032
 
1955
2033
  # VERSION HISTORY
1956
2034
 
2035
+
2036
+ #### 2025-07-05 v0.6.21
2037
+ •Now use new code insertion `--code-after-new` for code that happens directly after `.new()` call. use semicolon (`;`) to create linebreaks; no reason why the factories should insert flash messages
2038
+
2039
+ • removes duplicitous flash messages in factory context
2040
+
2041
+ • adds documentation for `--code-before-create`, `--code-after-create`, `--code-before-update`, `--code-after-update` (these features were already implemented)
2042
+
2043
+ • updates are now built using `.assign_attributes` followed by `.save` (previously, they were updated with one `.update()` call); this allows your Pundit policy to check if the changed values are valid and raise an exception if not allowed based on the changed data (can be checked on Rails models with `.changed` or `.changes`; see https://api.rubyonrails.org/classes/ActiveModel/Dirty.html)
2044
+
2045
+ • Fixes to timezone aware input. If your `current_user` (or auth object) has a method `timezone`, your datetime and time inputs will be timezone-aware.
2046
+
2047
+ If a timezone is present, datetimes & times will be converted from database-native UTC into the current user's timezone when displayed (either as viewable or editable)
2048
+
2049
+ If a user puts a time into the interface, it is assumed to be in the user's timezone and is converted to UTC before being saved.
2050
+
2051
+
2052
+ #### 2025-06-13 v0.6.20
2053
+ Breaking changes:
2054
+ • the setting in your hot_glue.yml file for `:pundit_default:` has been renamed just `:pundit:`.
2055
+ If you fail to rename it in your config file, hot glue will not build if it finds the old config setting.
2056
+
2057
+ • previously magic methods had a ability method that was the name of the magic method + `able?` as one word.
2058
+ this has been renamed to `_able?` and you must fix your cooresponding magic method ability methods by adding the underscore
2059
+
2060
+
2061
+ New Features
2062
+ • adds new invisibilty feature with `--invisible`, `--create-invisible`, and `--update-invisible` see docs above
2063
+ • changes previous `--hidden` into `--hidden`, `--create-hidden`, and `--update-hidden`. use hidden to apply to both fields
2064
+ • restores functionality of layout builder to magically distribute bootstrap 12 columns
2065
+ (4 columns use rows of 3 col widths; 2 columns use 6, 3 uses 4, etc). WHen using specified grouping mode, you
2066
+ probably want about 3 or 4 columns. When you have more than 5 it's difficult to build layouts that look good.
2067
+
2068
+
2069
+
1957
2070
  #### 2025-06-10 v0.6.19
1958
2071
 
1959
2072
  • Fixes magic button output behavior to correctly show the string returned by the bang menthod