hot-glue 0.6.1 → 0.6.2
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 +2 -2
- data/README.md +81 -12
- data/lib/generators/hot_glue/fields/association_field.rb +1 -2
- data/lib/generators/hot_glue/scaffold_generator.rb +25 -2
- data/lib/generators/hot_glue/templates/controller.rb.erb +29 -17
- data/lib/generators/hot_glue/templates/erb/_edit.erb +3 -1
- data/lib/generators/hot_glue/templates/erb/_new_form.erb +4 -1
- data/lib/generators/hot_glue/templates/typeahead_controller.rb.erb +1 -0
- data/lib/generators/hot_glue/typeahead_generator.rb +5 -1
- data/lib/hotglue/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c984f13c5f9639c6cea9837c4266cf0e4e529e9adef1dffea257551ebd80f8cd
|
4
|
+
data.tar.gz: ba87601c2e04556604a7900880f054fd67b95ee78c9113668664ffb591c0601f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9b1228beb6639f671f2138c0b62a891060da18089e23cb1a9f0518b77b0002e2c38018b18df49525f0dcf6b2715c6ed3c4c415bca8d203c8afad0c5113fad88
|
7
|
+
data.tar.gz: 34e37814fe29eb58097331279107b1b58a4e9dbb4f3f9887c0e5c6b095d484c8a893034d3dafeed2ffbd5350a3cbd7542ee7dba4ffbd0a149b04a4b6a936ab8c
|
data/.github/FUNDING.yml
CHANGED
@@ -1 +1 @@
|
|
1
|
-
custom: ["https://twitter.com/HotGlueForRails", "https://school.
|
1
|
+
custom: ["https://twitter.com/HotGlueForRails", "https://school.jfbcodes.com/8188?utm_source=github.com&utm_campaign=github_hot_glue_repo_funding_link"]
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hot-glue (0.6.
|
4
|
+
hot-glue (0.6.1)
|
5
5
|
ffaker (~> 2.16)
|
6
6
|
kaminari (~> 1.2)
|
7
7
|
rails (> 5.1)
|
@@ -139,7 +139,7 @@ GEM
|
|
139
139
|
mini_mime (1.1.2)
|
140
140
|
mini_portile2 (2.8.4)
|
141
141
|
minitest (5.16.3)
|
142
|
-
net-imap (0.4.
|
142
|
+
net-imap (0.4.5)
|
143
143
|
date
|
144
144
|
net-protocol
|
145
145
|
net-pop (0.1.2)
|
data/README.md
CHANGED
@@ -38,7 +38,7 @@ Other than the opinionated differences and additional features, Hot Glue produce
|
|
38
38
|
|
39
39
|
# Get Hot Glue
|
40
40
|
|
41
|
-
## [GET THE COURSE TODAY](https://school.
|
41
|
+
## [GET THE COURSE TODAY](https://school.jfbcodes.com/8188/?utm_source=github.com&utm_campaign=github_hot_glue_readme_page) **only $60 USD!**
|
42
42
|
|
43
43
|
|
44
44
|
---
|
@@ -522,7 +522,7 @@ The short form looks like this. It presumes there is a 'pets' association from `
|
|
522
522
|
|
523
523
|
(The long form equivalent of this would be `--hawk=pet_id{current_user.pets}`)
|
524
524
|
|
525
|
-
This is covered in [Example #3 in the Hot Glue Tutorial](https://school.
|
525
|
+
This is covered in [Example #3 in the Hot Glue Tutorial](https://school.jfbcodes.com/8188)
|
526
526
|
|
527
527
|
To hawk to a scope that is not the currently authenticated user, use the long form with `{...}`
|
528
528
|
to specify the scope. Be sure to note to add the association name itself, like `users`:
|
@@ -532,7 +532,7 @@ to specify the scope. Be sure to note to add the association name itself, like `
|
|
532
532
|
This would hawk the Appointment's `user_id` key to any users who are within the scope of the
|
533
533
|
current_user's has_many association (so, for any other "my" family, would be `current_user.family.users`).
|
534
534
|
|
535
|
-
This is covered in [Example #4 in the Hot Glue Tutorial](https://school.
|
535
|
+
This is covered in [Example #4 in the Hot Glue Tutorial](https://school.jfbcodes.com/8188)
|
536
536
|
|
537
537
|
|
538
538
|
### `--plural=`
|
@@ -691,11 +691,14 @@ If you enable Pundit, your controllers will look for a Policy that matches the n
|
|
691
691
|
**Realtime Field-level Access**
|
692
692
|
Hot Glue gives you automatic field level access control if you create `*_able?` methods for each field you'd like to control on your Pundit policy.
|
693
693
|
|
694
|
-
(Although this is not what Pundit recommends for field level access control, it has been implemented this way to provide field-by-field user feedback to the user shown in red just like Rails validation errors are currently shown.
|
694
|
+
(Although this is not what Pundit recommends for field level access control, it has been implemented this way to provide field-by-field user feedback to the user shown in red just like Rails validation errors are currently shown. A user having access to input text into a field they shouldn't have access to is *only hypothetical*, because the Hot Glue will correctly show the the user connect edit was view-only anyway, making unallowed entry only something that could be achieved through a mistake or hacking. Nevertheless, rest assured that if there was a input mistake-- like a user having a field editable when it shouldn't be, if you implement your backend policy correctly with an `update?` method guards against the disallowed input, your user will show an error message and the record will not be updated.)
|
695
|
+
|
696
|
+
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?`.
|
697
|
+
|
698
|
+
|
699
|
+
**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.**
|
695
700
|
|
696
|
-
The `*_able?` method should return true or false depending on whether or not the field can be edited. (No distinction is made between the different contexts. You may check if the record is new using `new_record?`.
|
697
701
|
|
698
|
-
The `*_able?` method is used by Hot Glue only on the new and edit actions, but you should incorporate it into the policy's `update?` method as in the example, which will extend other operations since Hot Glue will use the policy to authorize the action
|
699
702
|
Add one `*_able?` method to the policy for each field you want to allow field-level access control.
|
700
703
|
|
701
704
|
Replace `*` with the name of the field you want under access control. Remember to include `_id` for foreign keys. You do not need it for any field you don't want under access control.
|
@@ -852,7 +855,7 @@ This means you can be a somewhat lazy about your bang methods, but keep in mind
|
|
852
855
|
|
853
856
|
Finally, you can raise an ActiveRecord error which will also get passed to the user in the flash alert area.
|
854
857
|
|
855
|
-
For more information see Example 5 in the Tutorial
|
858
|
+
For more information see [Example 5 in the Tutorial](https://school.jfbcodes.com/8188)
|
856
859
|
|
857
860
|
|
858
861
|
### `--downnest`
|
@@ -980,7 +983,7 @@ rails generate hot_glue:scaffold User --related-sets=roles --include=email,roles
|
|
980
983
|
|
981
984
|
Note this leaves open a privileged escalation attack (a security vulnerability).
|
982
985
|
|
983
|
-
To fix this, you'll need to use Pundit with special syntax designed for this purpose. Please see Example #
|
986
|
+
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)
|
984
987
|
|
985
988
|
|
986
989
|
## "Thing" Label
|
@@ -1048,6 +1051,20 @@ Use `before` to make the labels come before or `after` to make them come after.
|
|
1048
1051
|
Omits the heading of column names that appears above the 1st row of data.
|
1049
1052
|
|
1050
1053
|
|
1054
|
+
|
1055
|
+
`--code-before-create`
|
1056
|
+
`--code-after-create`
|
1057
|
+
`--code-before-update`
|
1058
|
+
`--code-after-update`
|
1059
|
+
|
1060
|
+
Insert some code into the `create` action or `update` actions.
|
1061
|
+
The **before code** is called _after authorization_ but _before saving_ (which creates the record, or fails validation).
|
1062
|
+
The **after create** code is called after the record is saved (and thus has an id in the case of the create action).
|
1063
|
+
Both should be wrapped in quotation marks when specified in the command line, and use semicolons to separate multiple lines of code.
|
1064
|
+
(Notice the funky indentation of the lines in the generated code. Adjust you input to get the indentation correct.)
|
1065
|
+
|
1066
|
+
|
1067
|
+
|
1051
1068
|
## Special Features
|
1052
1069
|
|
1053
1070
|
### `--attachments`
|
@@ -1345,6 +1362,10 @@ Child portals have the headings omitted automatically (there is a heading identi
|
|
1345
1362
|
- Enum - displayed as a drop-down list (defined the enum values on your model).
|
1346
1363
|
- For Rails 6 see https://jasonfleetwoodboldt.com/courses/stepping-up-rails/enumerated-types-in-rails-and-postgres/
|
1347
1364
|
- You must specify the enum definition both in your model and also in your database migration for both Rails 6 + Rails 7
|
1365
|
+
- 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.
|
1366
|
+
|
1367
|
+
|
1368
|
+
|
1348
1369
|
|
1349
1370
|
# Note about enums
|
1350
1371
|
|
@@ -1389,6 +1410,8 @@ def self.status_labels
|
|
1389
1410
|
|
1390
1411
|
Now, your labels will show up on the front-end as defined in the `_labels` ("Is currently pending", etc) instead of the database-values.
|
1391
1412
|
|
1413
|
+
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.
|
1414
|
+
|
1392
1415
|
### Validation Magic
|
1393
1416
|
|
1394
1417
|
Use ActiveRecord validations or hooks to validate your data. Hot Glue will automatically display the errors in the UI.
|
@@ -1491,9 +1514,55 @@ For example, to display the field `my_story` on the object `Thing`, you'd genera
|
|
1491
1514
|
bin/rails generate Thing --include=my_story --modify='my_story{tinymce}'
|
1492
1515
|
```
|
1493
1516
|
|
1517
|
+
### Pickup Partial Includes for `_edit` and `_new` Screens
|
1518
|
+
|
1519
|
+
If you have a partial already in the view folder called `_edit_within_form.html.erb`, it with get included within the edit form.
|
1520
|
+
If you have a partial already in the view folder called `_new_within_form.html.erb`, it with get included within the new form.
|
1521
|
+
For these, you can use any of the objects by local variable name or the special `f` local variable to access the form itself.
|
1522
|
+
|
1523
|
+
These partials are good for including extra functionality in the form, like interactive widgets or hidden fields.
|
1524
|
+
If you have a partial already in the view folder called `_edit_after_form.html.erb`, it with get included **_after_** the edit form.
|
1525
|
+
If you have a partial already in the view folder called `_new_after_form.html.erb`, it with get included **_after_** the new form.
|
1526
|
+
You can use any of the objects by local variable name (but you cannot use the form object `f` because it is not in scope.)
|
1527
|
+
|
1528
|
+
The `within` partials should do operations within the form (like hidden fields), and the `after` partials should do entirely unrelated operations, like a different form entirely.
|
1529
|
+
|
1530
|
+
These automatic pickups for partials are detected at buildtime. This means that if you add these partials later, you must rebuild your scaffold.
|
1531
|
+
|
1532
|
+
|
1533
|
+
|
1534
|
+
|
1535
|
+
|
1494
1536
|
# VERSION HISTORY
|
1495
1537
|
|
1496
|
-
#### v0.6.
|
1538
|
+
#### 2023-12-02 - v0.6.2
|
1539
|
+
|
1540
|
+
• Fixes to typeahead when using Pundit.
|
1541
|
+
|
1542
|
+
• New Code Hooks: Add Custom Code Before/After the Update or Create Actions
|
1543
|
+
|
1544
|
+
`--code-before-create`
|
1545
|
+
`--code-after-create`
|
1546
|
+
`--code-before-update`
|
1547
|
+
`--code-after-update`
|
1548
|
+
|
1549
|
+
|
1550
|
+
Insert some code into the `create` action or `update` actions.
|
1551
|
+
|
1552
|
+
The **before code** is called _after authorization_ but _before saving_ (which creates the record, or fails validation).
|
1553
|
+
|
1554
|
+
The **after create** code is called after the record is saved (and thus has an id in the case of the create action).
|
1555
|
+
|
1556
|
+
Both should be wrapped in quotation marks when specified in the command line, and use semicolons to separate multiple lines of code.
|
1557
|
+
(Notice the funky indentation of the lines in the generated code. Adjust you input to get the indentation correct.)
|
1558
|
+
|
1559
|
+
• New Automatic Pickup Partial Includes for `_edit` and `_new` Screens
|
1560
|
+
|
1561
|
+
See "Pickup Partial Includes for `_edit` and `_new` Screens" above
|
1562
|
+
|
1563
|
+
|
1564
|
+
|
1565
|
+
#### 2023-11-21 - v0.6.1 - `--related-sets`
|
1497
1566
|
|
1498
1567
|
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.
|
1499
1568
|
|
@@ -1511,7 +1580,7 @@ Note that when making a scaffold like this, you may leave open a privileged esca
|
|
1511
1580
|
|
1512
1581
|
To fix this, you'll need to use Pundit with special syntax designed for this purpose.
|
1513
1582
|
|
1514
|
-
For a complete solution, please see Example
|
1583
|
+
For a complete solution, please see Example 17 in the [Hot Glue Tutorial](https://school.jfbcodes.com/8188).
|
1515
1584
|
|
1516
1585
|
Without Pundit, due to a quirk in how this code works with ActiveRecord, all update operates to the related sets table are permitted (and go through), even if the update operation otherwise fails validation for the fields on the object. (ActiveRecord doesn't seem to have a way to validate the related sets directly.)
|
1517
1586
|
|
@@ -1910,8 +1979,8 @@ License check has been removed (Hot Glue is now free to use for hobbyists and in
|
|
1910
1979
|
#### 2022-03-23 - v0.5.2 - Hawked Foreign Keys
|
1911
1980
|
|
1912
1981
|
- You can now protect your foreign keys from malicious input and also restrict the scope of drop downs to show only records with the specified access control restriction.
|
1913
|
-
- [Example #3](https://school.
|
1914
|
-
- [Example #4](https://school.
|
1982
|
+
- [Example #3](https://school.jfbcodes.com/8188) in the Hot Glue Tutorial shows you how to use the hawk to limit the scope to the logged in user.
|
1983
|
+
- [Example #4](https://school.jfbcodes.com/8188) in the Hot Glue Tutorial shows how to hawk to a non-usual scope, the inverse of the current user's belongs_to (that is, hawk the scope to X where current_user `belongs_to :x`)
|
1915
1984
|
|
1916
1985
|
|
1917
1986
|
#### 2022-03-12 - v0.5.1 - Inline List Labels
|
@@ -78,9 +78,8 @@ class AssociationField < Field
|
|
78
78
|
def form_field_output
|
79
79
|
assoc_name = name.to_s.gsub("_id","")
|
80
80
|
assoc = eval("#{class_name}.reflect_on_association(:#{assoc_name})")
|
81
|
-
|
82
81
|
if modify_as && modify_as[:typeahead]
|
83
|
-
search_url = "#{namespace ? namespace + "_" : ""}#{assoc.
|
82
|
+
search_url = "#{namespace ? namespace + "_" : ""}#{assoc.class_name.downcase.pluralize}_typeahead_index_url"
|
84
83
|
"<div class='typeahead typeahead--#{assoc.name}_id'
|
85
84
|
data-controller='typeahead'
|
86
85
|
data-typeahead-url-value='<%= #{search_url} %>'
|
@@ -90,6 +90,10 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
90
90
|
class_option :display_as, default: {}
|
91
91
|
class_option :pundit, default: nil
|
92
92
|
class_option :related_sets, default: ''
|
93
|
+
class_option :code_before_create, default: nil
|
94
|
+
class_option :code_after_create, default: nil
|
95
|
+
class_option :code_before_update, default: nil
|
96
|
+
class_option :code_after_update, default: nil
|
93
97
|
|
94
98
|
def initialize(*meta_args)
|
95
99
|
super
|
@@ -426,6 +430,11 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
426
430
|
@no_field_form = true
|
427
431
|
end
|
428
432
|
|
433
|
+
@code_before_create = options['code_before_create']
|
434
|
+
@code_after_create = options['code_after_create']
|
435
|
+
@code_before_update = options['code_before_update']
|
436
|
+
@code_after_update = options['code_after_update']
|
437
|
+
|
429
438
|
buttons_width = ((!@no_edit && 1) || 0) + ((!@no_delete && 1) || 0) + @magic_buttons.count
|
430
439
|
|
431
440
|
|
@@ -724,8 +733,17 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
724
733
|
if @factory_creation == ''
|
725
734
|
"@#{singular } = #{ class_name }.new(modified_params)"
|
726
735
|
else
|
727
|
-
|
728
|
-
|
736
|
+
res = +"begin
|
737
|
+
#{@factory_creation}
|
738
|
+
"
|
739
|
+
res << "\n" + "@#{singular} = factory.#{singular}" unless res.include?("@#{singular} = factory.#{singular}")
|
740
|
+
res << "flash[:notice] = \"Successfully created \#{@#{singular}.name}\" unless @#{singular}.new_record?
|
741
|
+
rescue ActiveRecord::RecordInvalid
|
742
|
+
@#{singular} = factory.#{singular}
|
743
|
+
flash[:alert] = \"Oops, your #{singular} could not be created. #{@hawk_alarm}\"
|
744
|
+
@action = 'new'
|
745
|
+
end"
|
746
|
+
res
|
729
747
|
end
|
730
748
|
end
|
731
749
|
|
@@ -743,6 +761,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
743
761
|
|
744
762
|
def copy_controller_and_spec_files
|
745
763
|
@default_colspan = @columns.size
|
764
|
+
|
746
765
|
unless @specs_only || @no_controller
|
747
766
|
template "controller.rb.erb", File.join("#{filepath_prefix}app/controllers#{namespace_with_dash}", "#{@controller_build_folder}_controller.rb")
|
748
767
|
if @namespace
|
@@ -1086,6 +1105,10 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
1086
1105
|
|
1087
1106
|
def copy_view_files
|
1088
1107
|
return if @specs_only
|
1108
|
+
@edit_within_form_partial = File.exist?("#{filepath_prefix}app/views#{namespace_with_dash}/#{@controller_build_folder}/_edit_within_form.html.#{@markup}")
|
1109
|
+
@edit_after_form_partial = File.exist?("#{filepath_prefix}app/views#{namespace_with_dash}/#{@controller_build_folder}/_edit_within_form.html.#{@markup}")
|
1110
|
+
@new_within_form_partial = File.exist?("#{filepath_prefix}app/views#{namespace_with_dash}/#{@controller_build_folder}/_new_within_form.html.#{@markup}")
|
1111
|
+
@new_after_form_partial = File.exist?("#{filepath_prefix}app/views#{namespace_with_dash}/#{@controller_build_folder}/_new_within_form.html.#{@markup}")
|
1089
1112
|
|
1090
1113
|
if @no_controller
|
1091
1114
|
File.write("#{Rails.root}/app/views/#{namespace_with_trailing_dash}/#{plural}/REGENERATE.md", regenerate_me_code)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class <%= controller_class_name %> < <%= controller_descends_from %>
|
2
4
|
# regenerate this controller with
|
3
5
|
<% if defined?(RuboCop) %># rubocop:disable Layout/LineLength
|
@@ -20,7 +22,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
20
22
|
|
21
23
|
nest_chain << arg %>
|
22
24
|
before_action :<%= arg[:singular] %><%= ", if: -> { params.include?(:#{arg[:singular]}_id) }" if arg[:optional] %><% } %><% end %>
|
23
|
-
before_action :load_<%= singular_name %>, only: [
|
25
|
+
before_action :load_<%= singular_name %>, only: %i[show edit update destroy]
|
24
26
|
after_action -> { flash.discard }, if: -> { request.format.symbol == :turbo_stream }
|
25
27
|
<% if @nested_set.any? %>def <%= @nested_set[0][:singular] %><% if @god
|
26
28
|
next_object = nil
|
@@ -83,18 +85,18 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
83
85
|
load_all_<%= plural %><% if @pundit %><% if @pundit %>
|
84
86
|
authorize @<%= plural_name %><% end %>
|
85
87
|
rescue Pundit::NotAuthorizedError
|
86
|
-
flash[:alert] =
|
87
|
-
render
|
88
|
+
flash[:alert] = 'You are not authorized to perform this action.'
|
89
|
+
render 'layouts/error'<% end %>
|
88
90
|
end
|
89
91
|
|
90
92
|
<% if create_action %> def new<% if @object_owner_sym %>
|
91
|
-
@<%= singular_name %> = <% if @pundit %>policy_scope(<% end %><%= class_name %><% if @pundit %>)<% end %>.new
|
93
|
+
@<%= singular_name %> = <% if @pundit %>policy_scope(<% end %><%= class_name %><% if @pundit %>)<% end %>.new<% if eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>(<%= @object_owner_sym %>: <%= @object_owner_eval %>)<% end %><% elsif @object_owner_optional && any_nested? %>
|
92
94
|
@<%= singular_name %> = <% if @pundit %>policy_scope(<% end %><%= class_name %><% if @pundit %>)<% end %>.new({}.merge(<%= @nested_set.last[:singular] %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}))<% else %>
|
93
95
|
@<%= singular_name %> = <% if @pundit %>policy_scope(<% end %><%= class_name %><% if @pundit %>)<% end %>.new(<% if any_nested? %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)<% end %>
|
94
96
|
<% if @pundit %>authorize @<%= singular_name %><% end %><% if @pundit %>
|
95
|
-
@action =
|
97
|
+
@action = 'new'
|
96
98
|
rescue Pundit::NotAuthorizedError
|
97
|
-
flash[:alert] =
|
99
|
+
flash[:alert] = 'You are not authorized to perform this action.'
|
98
100
|
load_all_users
|
99
101
|
render :index<% end %>
|
100
102
|
end
|
@@ -112,36 +114,39 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
112
114
|
<% if @pundit %><% @related_sets.each do |key, related_set| %>
|
113
115
|
check_<%= related_set[:association_ids_method].to_s %>_permissions(modified_params, :create)<% end %><% end %>
|
114
116
|
<% if @pundit %>authorize @<%= singular %><% end %>
|
115
|
-
|
116
|
-
if @<%= singular_name %>.save
|
117
|
+
<%= @code_before_create ? "\n " + @code_before_create.gsub(";", "\n") : "" %>
|
118
|
+
if @<%= singular_name %>.save<%= @code_after_create ? ("\n " + @code_after_create.gsub(";", "\n")) : ""%>
|
117
119
|
flash[:notice] = "Successfully created #{@<%= singular %>.<%= display_class %>}"
|
118
120
|
<%= post_action_parental_updates %>
|
119
121
|
load_all_<%= plural %>
|
120
122
|
render :create
|
121
123
|
else
|
122
124
|
flash[:alert] = "Oops, your <%= singular_name %> could not be created. #{@hawk_alarm}"
|
123
|
-
@action =
|
125
|
+
@action = 'new'
|
124
126
|
render :create, status: :unprocessable_entity
|
125
127
|
end<% if @pundit %>
|
126
128
|
rescue Pundit::NotAuthorizedError
|
127
|
-
flash[:alert]
|
129
|
+
flash[:alert] << 'Creating organization not authorized. '
|
130
|
+
flash[:alert] << @<%= singular %>.errors.collect{|k| "#{k.attribute} #{k.message}"}.join(" ")
|
131
|
+
flash[:alert] << flash[:notice]
|
128
132
|
render :index <% end %>
|
129
133
|
end
|
130
134
|
|
131
135
|
<% end %>
|
132
136
|
<% unless @no_edit %>
|
133
137
|
def show
|
138
|
+
<% if @pundit %>authorize @<%= singular %><% end %>
|
134
139
|
redirect_to <%= HotGlue.optionalized_ternary(namespace: @namespace,
|
135
140
|
target: @singular,
|
136
141
|
nested_set: @nested_set,
|
137
|
-
modifier:
|
142
|
+
modifier: 'edit_',
|
138
143
|
with_params: true,
|
139
144
|
put_form: true).gsub("(#{singular}", "(@#{singular}") %>
|
140
145
|
end
|
141
146
|
|
142
147
|
def edit<% if @pundit %>
|
143
148
|
authorize @<%= singular_name %><% end %>
|
144
|
-
@action =
|
149
|
+
@action = 'edit'
|
145
150
|
render :edit<% if @pundit %>
|
146
151
|
rescue Pundit::NotAuthorizedError
|
147
152
|
flash[:alert] = "Editing #{@<%= singular %>.<%= display_class %>} not authorized."
|
@@ -166,21 +171,24 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
166
171
|
check_<%= related_set[:association_ids_method].to_s %>_permissions(modified_params, :update)<% end %><% end %>
|
167
172
|
|
168
173
|
<% if @hawk_keys.any? %> modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
|
169
|
-
|
174
|
+
<%= controller_attachment_orig_filename_pickup_syntax %>
|
170
175
|
<% if @pundit %>
|
171
176
|
if @<%= singular_name %>.attributes = modified_params
|
172
177
|
authorize @<%= singular_name %>
|
178
|
+
<%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
|
173
179
|
@<%= singular_name %>.save
|
174
180
|
<% else %>
|
181
|
+
<%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
|
175
182
|
if @<%= singular_name %>.update(modified_params)
|
176
183
|
<% end %>
|
184
|
+
<%= @code_after_update ? "\n " + @code_after_update.gsub(";", "\n") : "" %>
|
177
185
|
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
178
186
|
flash[:notice] << "Saved #{@<%= singular %>.<%= display_class %>}"
|
179
187
|
flash[:alert] = @hawk_alarm if @hawk_alarm
|
180
188
|
render :update
|
181
189
|
else
|
182
190
|
flash[:alert] = "<%= singular_name.titlecase %> could not be saved. #{@hawk_alarm}"
|
183
|
-
@action =
|
191
|
+
@action = 'edit'
|
184
192
|
render :update, status: :unprocessable_entity
|
185
193
|
end<% if @pundit %>
|
186
194
|
rescue Pundit::NotAuthorizedError
|
@@ -204,9 +212,13 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
204
212
|
|
205
213
|
<% if @pundit %><% @related_sets.each do |key, rs| %>
|
206
214
|
def check_<%= rs[:association_ids_method] %>_permissions(modified_params, action)
|
207
|
-
if modified_params[:<%= rs[:association_ids_method] %>].present? &&
|
208
|
-
|
209
|
-
|
215
|
+
if modified_params[:<%= rs[:association_ids_method] %>].present? &&
|
216
|
+
modified_params[:<%= rs[:association_ids_method] %>] != @<%= singular %>.<%= rs[:association_ids_method] %>
|
217
|
+
# authorize the <%= rs[:association_ids_method] %> change using special modified_relations: {
|
218
|
+
# <%= rs[:association_ids_method] %>: modified_params[:<%= rs[:association_ids_method] %>>]} syntax for Pundit
|
219
|
+
if ! <%= singular_class %>Policy.new(current_user, @<%= singular %>,
|
220
|
+
modified_relations: {role_ids: modified_params[:<%= rs[:association_ids_method] %>]
|
221
|
+
}).method("#{action}?".to_sym).call
|
210
222
|
authorize @<%= singular %>, "#{action}?".to_sym
|
211
223
|
raise Pundit::NotAuthorizedError, message: @<%= singular %>.errors.collect{|k| "#{k.attribute} #{k.message}"}.join(" ")
|
212
224
|
end
|
@@ -5,7 +5,9 @@
|
|
5
5
|
<\% end %>
|
6
6
|
<h2>Editing <\%= <%= singular %>.<%= display_class %> %></h2>
|
7
7
|
<\%= form_with model: <%= singular %>, url: <%= form_path_edit_helper %> do |f| %>
|
8
|
-
|
8
|
+
<\%= render partial: "<%= namespace_with_trailing_dash + @controller_build_folder + "/" %>form", locals: {:<%= singular %> => <%= singular %>, f: f}<%= @nested_set.collect{|arg| ".merge(#{arg[:singular]} ? {#{arg[:singular]}: #{arg[:singular]}} : {})" }.join %> \%>
|
9
|
+
<% if @edit_within_form_partial %><\%= render partial: "edit_within_form", locals: {f: f, <%= singular %>: <%= singular %>}<%= @nested_set.collect{|arg| ".merge(#{arg[:singular]} ? {#{arg[:singular]}: #{arg[:singular]}} : {})" }.join %> %><% end %>
|
9
10
|
<\% end %>
|
11
|
+
<% if @edit_within_form_partial %><\%= render partial: "edit_after_form", locals: {<%= singular %>: <%= singular %>}<%= @nested_set.collect{|arg| ".merge(#{arg[:singular]} ? {#{arg[:singular]}: #{arg[:singular]}} : {})" }.join %> %><% end %>
|
10
12
|
</div>
|
11
13
|
<\% end %>
|
@@ -5,5 +5,8 @@
|
|
5
5
|
<\%= form_with model: <%= singular %>, url: <%= form_path_new_helper %>, method: :post do |f| \%>
|
6
6
|
<\%= render partial: "<%= namespace_with_slash + @controller_build_folder %>/form",
|
7
7
|
locals: { <%= singular %>: <%= singular %>, f: f}<%= @nested_set.collect{|arg| ".merge(defined?(#{arg[:singular]}) ? {#{arg[:singular]}: #{arg[:singular]}}: {})" }.join %> \%>
|
8
|
-
|
8
|
+
|
9
|
+
<% if @new_within_form_partial %><\%= render partial: "new_within_form", locals: {f: f, <%= singular %>: <%= singular %>}<%= @nested_set.collect{|arg| ".merge(#{arg[:singular]} ? {#{arg[:singular]}: #{arg[:singular]}} : {})" }.join %> %><% end %>
|
10
|
+
<\% end %>
|
11
|
+
<% if @new_after_form_partial %><\%= render partial: "new_after_form", locals: {<%= singular %>: <%= singular %>}<%= @nested_set.collect{|arg| ".merge(#{arg[:singular]} ? {#{arg[:singular]}: #{arg[:singular]}} : {})" }.join %> %><% end %>
|
9
12
|
<\% end %>
|
@@ -5,6 +5,7 @@ class <%= ((@namespace.titleize.gsub(" ", "") + "::" if @namespace) || "") + @pl
|
|
5
5
|
# rubocop:enable Layout/LineLength <% end %>
|
6
6
|
|
7
7
|
def index
|
8
|
+
<% if @pundit %>authorize <%= @class_name %>, :typeahead? <% end %>
|
8
9
|
query = params[:query]
|
9
10
|
@typeahead_identifier = params[:typeahead_identifier]
|
10
11
|
@<%= @plural %> = <%= @singular.titleize.gsub(" ", "") %>.where("<%= @search_by.collect{|search| "LOWER(#{search}) LIKE ?" }.join(" OR ") %>", <%= @search_by.collect{|search| "\"%\#{query.downcase}%\"" }.join(", ") %>).limit(10)
|
@@ -1,9 +1,12 @@
|
|
1
|
+
require_relative './default_config_loader'
|
2
|
+
|
1
3
|
module HotGlue
|
2
4
|
class TypeaheadGenerator < Rails::Generators::Base
|
3
5
|
source_root File.expand_path('templates', __dir__)
|
4
6
|
class_option :namespace, type: :string, default: nil
|
5
7
|
class_option :search_by, type: :string, default: nil
|
6
8
|
|
9
|
+
include DefaultConfigLoader
|
7
10
|
def filepath_prefix
|
8
11
|
# todo: inject the context
|
9
12
|
'spec/dummy/' if $INTERNAL_SPECS
|
@@ -19,9 +22,10 @@ module HotGlue
|
|
19
22
|
puts message
|
20
23
|
raise(HotGlue::Error, message)
|
21
24
|
end
|
25
|
+
@pundit = get_default_from_config(key: :pundit_default)
|
22
26
|
|
23
27
|
@singular = args.first.tableize.singularize
|
24
|
-
|
28
|
+
@class_name = args.first
|
25
29
|
@plural = args.first.tableize.pluralize
|
26
30
|
@namespace = options['namespace']
|
27
31
|
|
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.6.
|
4
|
+
version: 0.6.2
|
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: 2023-
|
11
|
+
date: 2023-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '2.16'
|
55
55
|
description: Simple, plug & play Rails scaffold building companion for Turbo-Rails
|
56
56
|
and Hotwire
|
57
|
-
email:
|
57
|
+
email: hello@jfbcodes.com
|
58
58
|
executables: []
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|