hot-glue 0.6.15 → 0.6.16
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +50 -0
- data/lib/generators/hot_glue/field_factory.rb +3 -2
- data/lib/generators/hot_glue/fields/enum_field.rb +1 -0
- data/lib/generators/hot_glue/layout/builder.rb +19 -7
- data/lib/generators/hot_glue/layout_strategy/bootstrap.rb +6 -6
- data/lib/generators/hot_glue/layout_strategy/hot_glue.rb +3 -3
- data/lib/generators/hot_glue/layout_strategy/tailwind.rb +3 -3
- data/lib/generators/hot_glue/markup_templates/erb.rb +18 -14
- data/lib/generators/hot_glue/scaffold_generator.rb +2 -2
- data/lib/generators/hot_glue/templates/controller.rb.erb +36 -18
- data/lib/generators/hot_glue/templates/erb/edit.erb +23 -13
- data/lib/hotglue/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09ebf223206d1bf224f02aaafe2796774bfa6b3d61c6892c1b0144ec2a8dd0f3'
|
4
|
+
data.tar.gz: 1fd04b5e1909ebcf2ecc9eeb5c4e212f7a6878d49c0fe918305e43e441cd73d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c01e39699fe999a7024850b9d738d5e205b4e5abe8c39d3619d10efa74fbed2384ac6cadfa4010d52c0a9fdea3878ae599aa23002cd439d323701f4b8524c3eb
|
7
|
+
data.tar.gz: 79c20e1f78772f79e396cecfc81990a70b3a0d17988962baebd6c2ea0b10eabedea59ebd8624f34d0ad7ce864d59bf7ad7be2afb8c712ef01f605ab06e272fce
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -790,6 +790,23 @@ end
|
|
790
790
|
Because Hot Glue detects the `*_able?` methods at build time, if you add them to your policy, you will have to rebuild your scaffold.
|
791
791
|
|
792
792
|
|
793
|
+
### `--pundit-policy-override`
|
794
|
+
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.
|
795
|
+
|
796
|
+
example
|
797
|
+
|
798
|
+
`rails generate hot_glue:scaffold Invoice --gd --pundit-policy-override='UniqueInvoicePolicy'`
|
799
|
+
|
800
|
+
You will implement a Pundit policy for `UniqueInvoicePolicy` and it should implement actions with question mark `?` endings corresponding to the same actions you are building, `new?`, `create?`, `edit?`, `update?`, and `destroy?`
|
801
|
+
|
802
|
+
If provided, the output code looks something like (in this example, showing the `edit?` method)
|
803
|
+
|
804
|
+
```
|
805
|
+
skip_authorization
|
806
|
+
raise Pundit::NotAuthorizedError if ! UniqueInvoicePolicy.edit?
|
807
|
+
```
|
808
|
+
|
809
|
+
|
793
810
|
### `--show-only=`
|
794
811
|
(separate field names by COMMA)
|
795
812
|
|
@@ -1751,6 +1768,39 @@ These automatic pickups for partials are detected at build time. This means that
|
|
1751
1768
|
|
1752
1769
|
# VERSION HISTORY
|
1753
1770
|
|
1771
|
+
#### 2025-03-31 v0.6.16
|
1772
|
+
|
1773
|
+
• Bootstrap Tab Panes For Downnested Portals
|
1774
|
+
Downnested portals are now built with bootstrap tab panes (always) and are no longer stacked on top of one another.
|
1775
|
+
|
1776
|
+
It looks like this:
|
1777
|
+
https://getbootstrap.com/docs/5.0/components/navs-tabs/#javascript-behavior
|
1778
|
+
|
1779
|
+
• inline_list_labels can be set in hot_glue.yml
|
1780
|
+
• typeaheads nested inside of routes are fixed
|
1781
|
+
• switches back to current_timezone implementation, displaying times relative to the user's set timezone
|
1782
|
+
• load all code now sets query parameters
|
1783
|
+
|
1784
|
+
• Pundit Policy Override
|
1785
|
+
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.
|
1786
|
+
|
1787
|
+
example
|
1788
|
+
|
1789
|
+
`rails generate hot_glue:scaffold Invoice --gd --pundit-policy-override='UniqueInvoicePolicy'`
|
1790
|
+
|
1791
|
+
Implement `UniqueInvoicePolicy` using actions with question mark `?` endings corresponding to the same actions you are building, `new?`, `create?`, `edit?`, `update?`, and `destroy?`
|
1792
|
+
|
1793
|
+
|
1794
|
+
• Bootstrap column builder has been changed.
|
1795
|
+
The bootstrap column bulder previously defaulted all real columns to col-sm-2 (or whichever bootstrap column with you set)
|
1796
|
+
|
1797
|
+
The builder has been refactored to allow for a per-column width generated automatically by the builder. If there are unused bootstrap columns, the builder will add width to the first columns in your layout, making them wider.
|
1798
|
+
|
1799
|
+
|
1800
|
+
|
1801
|
+
|
1802
|
+
|
1803
|
+
|
1754
1804
|
#### 2025-03-17 - v0.6.15
|
1755
1805
|
|
1756
1806
|
• now store on your current_user model (this is automatically passed into the method modify_date_inputs_on_params). HG will set user-inputted values correctly to daylight savings time during April-Nov months only (#195)
|
@@ -12,8 +12,6 @@ require_relative "fields/uuid_field"
|
|
12
12
|
require_relative "fields/attachment_field"
|
13
13
|
require_relative "fields/related_set_field"
|
14
14
|
|
15
|
-
|
16
|
-
|
17
15
|
class FieldFactory
|
18
16
|
attr_accessor :field, :class_name
|
19
17
|
def initialize(type: , name: , generator: )
|
@@ -51,6 +49,9 @@ class FieldFactory
|
|
51
49
|
end
|
52
50
|
@class_name = class_name
|
53
51
|
|
52
|
+
if field_class.nil?
|
53
|
+
raise "Field type could be identified #{name} "
|
54
|
+
end
|
54
55
|
|
55
56
|
@field = field_class.new(name: name,
|
56
57
|
layout_strategy: generator.layout_strategy,
|
@@ -32,6 +32,7 @@ class EnumField < Field
|
|
32
32
|
|
33
33
|
def form_field_output
|
34
34
|
enum_type = eval("#{class_name}.columns.select{|x| x.name == '#{name}'}[0].sql_type")
|
35
|
+
|
35
36
|
if eval("defined? #{class_name}.#{enum_type}_labels") == "method"
|
36
37
|
enum_definer = "#{class_name}.#{enum_type}_labels"
|
37
38
|
else
|
@@ -40,7 +40,8 @@ module HotGlue
|
|
40
40
|
layout_object = {
|
41
41
|
columns: {
|
42
42
|
size_each: smart_layout ? bootstrap_column_width : (specified_grouping_mode ? nil : 1),
|
43
|
-
container: [] # array of arrays
|
43
|
+
container: [] , # array of arrays,
|
44
|
+
bootstrap_column_width: []
|
44
45
|
},
|
45
46
|
portals: {
|
46
47
|
|
@@ -99,7 +100,7 @@ module HotGlue
|
|
99
100
|
}
|
100
101
|
layout_object[:columns][:container] = (0..available_columns-1).collect { |x| [columns[x]] }
|
101
102
|
layout_object[:columns][:container].reject!{|x| x == [nil]}
|
102
|
-
layout_object[:columns][:size_each] = bootstrap_column_width
|
103
|
+
# layout_object[:columns][:size_each] = bootstrap_column_width
|
103
104
|
end
|
104
105
|
elsif ! specified_grouping_mode
|
105
106
|
# not smart and no specified grouping
|
@@ -117,22 +118,33 @@ module HotGlue
|
|
117
118
|
# input control
|
118
119
|
|
119
120
|
user_layout_columns = @include_setting.split(":")
|
120
|
-
size_each = (bootstrap_columns / user_layout_columns.count).floor # this is the bootstrap size
|
121
121
|
|
122
|
-
|
122
|
+
extra_columns = available_columns - user_layout_columns.size
|
123
|
+
# size_each = (bootstrap_columns / user_layout_columns.count).floor # this is the bootstrap size
|
124
|
+
#
|
125
|
+
# layout_object[:columns][:size_each] = size_each
|
123
126
|
|
124
|
-
if user_layout_columns.size > available_columns
|
125
|
-
|
126
|
-
end
|
127
|
+
# if user_layout_columns.size > available_columns
|
128
|
+
# raise "Your include statement #{@include_setting } has #{user_layout_columns.size} columns, but I can only construct up to #{available_columns}"
|
129
|
+
# end
|
127
130
|
user_layout_columns.each_with_index do |column,i|
|
128
131
|
layout_object[:columns][:container][i] = column.split(",").collect(&:to_sym)
|
132
|
+
|
133
|
+
default_col_width = 1
|
134
|
+
if extra_columns > 0
|
135
|
+
default_col_width += 1
|
136
|
+
extra_columns -= 1
|
137
|
+
end
|
138
|
+
layout_object[:columns][:bootstrap_column_width][i] = default_col_width
|
129
139
|
end
|
130
140
|
|
131
141
|
if user_layout_columns.size < layout_object[:columns][:container].size
|
132
142
|
layout_object[:columns][:container].reject!{|x| x == []}
|
133
143
|
end
|
144
|
+
|
134
145
|
end
|
135
146
|
|
147
|
+
|
136
148
|
puts "*** constructed smart layout columns #{layout_object.inspect}"
|
137
149
|
layout_object
|
138
150
|
end
|
@@ -17,20 +17,20 @@ class LayoutStrategy::Bootstrap < LayoutStrategy::Base
|
|
17
17
|
end
|
18
18
|
|
19
19
|
|
20
|
-
def column_classes_for_form_fields
|
21
|
-
"col-md-#{builder.layout_object[:columns][:size_each]}"
|
20
|
+
def column_classes_for_form_fields(size = nil)
|
21
|
+
"col-md-#{size || builder.layout_object[:columns][:size_each]}"
|
22
22
|
end
|
23
23
|
|
24
|
-
def column_classes_for_column_headings
|
25
|
-
column_classes_for_line_fields
|
24
|
+
def column_classes_for_column_headings(size = nil)
|
25
|
+
column_classes_for_line_fields(size)
|
26
26
|
end
|
27
27
|
|
28
28
|
def container_name
|
29
29
|
"container"
|
30
30
|
end
|
31
31
|
|
32
|
-
def column_classes_for_line_fields
|
33
|
-
"col-sm-#{builder.layout_object[:columns][:size_each]}"
|
32
|
+
def column_classes_for_line_fields(size = nil)
|
33
|
+
"col-sm-#{size || builder.layout_object[:columns][:size_each]}"
|
34
34
|
end
|
35
35
|
|
36
36
|
def column_width
|
@@ -39,18 +39,18 @@ class LayoutStrategy::HotGlue < LayoutStrategy::Base
|
|
39
39
|
"scaffold-row"
|
40
40
|
end
|
41
41
|
|
42
|
-
def column_classes_for_form_fields
|
42
|
+
def column_classes_for_form_fields(size = nil)
|
43
43
|
"scaffold-cell"
|
44
44
|
end
|
45
45
|
|
46
46
|
def row_heading_classes
|
47
47
|
"scaffold-heading-row"
|
48
48
|
end
|
49
|
-
def column_classes_for_line_fields
|
49
|
+
def column_classes_for_line_fields(size = nil)
|
50
50
|
"scaffold-cell"
|
51
51
|
end
|
52
52
|
|
53
|
-
def column_classes_for_column_headings
|
53
|
+
def column_classes_for_column_headings(size = nil)
|
54
54
|
"scaffold-cell"
|
55
55
|
end
|
56
56
|
|
@@ -6,9 +6,9 @@ class LayoutStrategy::Tailwind < LayoutStrategy::Base
|
|
6
6
|
def button_style ; ""; end
|
7
7
|
def column_headings_col_style; "" ; end
|
8
8
|
def column_width; ""; end
|
9
|
-
def column_classes_for_line_fields; ""; end
|
10
|
-
def column_classes_for_form_fields; ""; end
|
11
|
-
def column_classes_for_column_headings; ""; end
|
9
|
+
def column_classes_for_line_fields(size = nil); ""; end
|
10
|
+
def column_classes_for_form_fields(size = nil); ""; end
|
11
|
+
def column_classes_for_column_headings(size = nil); ""; end
|
12
12
|
def col_width; 100; end
|
13
13
|
def container_name; ""; end
|
14
14
|
def downnest_style ; ""; end
|
@@ -76,13 +76,14 @@ module HotGlue
|
|
76
76
|
}.join("\n")
|
77
77
|
end
|
78
78
|
|
79
|
-
def list_column_headings(
|
80
|
-
column_width:, singular: )
|
79
|
+
def list_column_headings(column_width:, singular: )
|
81
80
|
col_style = @layout_strategy.column_headings_col_style
|
82
81
|
|
83
82
|
columns = layout_object[:columns][:container]
|
84
|
-
result = columns.map{ |column|
|
85
|
-
|
83
|
+
result = columns.map.with_index{ |column,i|
|
84
|
+
|
85
|
+
size = layout_object[:columns][:bootstrap_column_width][i]
|
86
|
+
"<div class='#{layout_strategy.column_classes_for_column_headings(size)} hg-heading-row heading--#{singular}--#{column.join("-")}' " + col_style + ">" +
|
86
87
|
column.map(&:to_s).map{|col_name| "#{col_name.humanize}"}.join("<br />") + "</div>"
|
87
88
|
}.join("\n")
|
88
89
|
return result
|
@@ -95,7 +96,6 @@ module HotGlue
|
|
95
96
|
|
96
97
|
def search_input_area
|
97
98
|
columns = layout_object[:columns][:container]
|
98
|
-
column_classes = layout_strategy.column_classes_for_form_fields
|
99
99
|
|
100
100
|
res =+ "<\%= form_with url: #{form_path}, method: :get, html: {'data-turbo-action': 'advance', 'data-controller': 'search-form'} do |f| %>"
|
101
101
|
res << "<div class=\"#{@layout_strategy.row_classes} search--#{@plural}\">"
|
@@ -116,12 +116,13 @@ module HotGlue
|
|
116
116
|
end
|
117
117
|
}.compact.join("\n")
|
118
118
|
|
119
|
-
|
119
|
+
size = layout_object[:columns][:bootstrap_column_width][columns.index(column)]
|
120
|
+
" <div class='#{layout_strategy.column_classes_for_form_fields(size)} search-cell--#{singular}--#{column.join("-")}' >" +
|
120
121
|
cols_result + "</div>"
|
121
122
|
|
122
123
|
}.join("\n")
|
123
124
|
res << "</div>"
|
124
|
-
res << "<div class='#{
|
125
|
+
res << "<div class='#{layout_strategy.column_classes_for_form_fields(nil)}'>"
|
125
126
|
if @search_clear_button
|
126
127
|
res << "<\%= f.button \"Clear\", name: nil, 'data-search-form-target': 'clearButton', class: 'btn btn-sm btn-secondary' %>"
|
127
128
|
end
|
@@ -132,11 +133,12 @@ module HotGlue
|
|
132
133
|
|
133
134
|
|
134
135
|
def all_form_fields(layout_strategy:)
|
135
|
-
column_classes = layout_strategy.column_classes_for_form_fields
|
136
136
|
columns = layout_object[:columns][:container]
|
137
137
|
|
138
138
|
result = columns.map{ |column|
|
139
|
-
|
139
|
+
size = layout_object[:columns][:bootstrap_column_width][columns.index(column)]
|
140
|
+
|
141
|
+
" <div class='#{layout_strategy.column_classes_for_form_fields(size)} cell--#{singular}--#{column.join("-")}' >" +
|
140
142
|
column.map { |col|
|
141
143
|
|
142
144
|
field_error_name = columns_map[col].field_error_name
|
@@ -192,10 +194,8 @@ module HotGlue
|
|
192
194
|
################################################################
|
193
195
|
|
194
196
|
def all_line_fields(layout_strategy:,
|
195
|
-
perc_width
|
196
|
-
col_identifier: nil)
|
197
|
+
perc_width:)
|
197
198
|
|
198
|
-
@col_identifier = layout_strategy.column_classes_for_line_fields
|
199
199
|
|
200
200
|
inline_list_labels = @inline_list_labels || 'omit'
|
201
201
|
columns = layout_object[:columns][:container]
|
@@ -205,9 +205,11 @@ module HotGlue
|
|
205
205
|
|
206
206
|
style_with_flex_basis = layout_strategy.style_with_flex_basis(perc_width)
|
207
207
|
|
208
|
-
result = columns.map{ |column|
|
208
|
+
result = columns.map.with_index{ |column,i|
|
209
209
|
|
210
|
-
|
210
|
+
size = layout_object[:columns][:bootstrap_column_width][i]
|
211
|
+
|
212
|
+
"<div class='hg-col #{layout_strategy.column_classes_for_line_fields(size)} #{singular}--#{column.join("-")}'#{style_with_flex_basis}> " +
|
211
213
|
column.map { |col|
|
212
214
|
if eval("#{singular_class}.columns_hash['#{col}']").nil? && !attachments.keys.include?(col) && !related_sets.include?(col)
|
213
215
|
raise "Can't find column '#{col}' on #{singular_class}, are you sure that is the column name?"
|
@@ -219,6 +221,8 @@ module HotGlue
|
|
219
221
|
"#{inline_list_labels == 'before' ? label + "<br/>" : ''}#{field_output}#{inline_list_labels == 'after' ? "<br/>" + label : ''}"
|
220
222
|
}.join( "<br />") + "</div>"
|
221
223
|
}.join("\n")
|
224
|
+
return result
|
225
|
+
|
222
226
|
end
|
223
227
|
end
|
224
228
|
end
|
@@ -91,6 +91,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
91
91
|
class_option :modify, default: {}
|
92
92
|
class_option :display_as, default: {}
|
93
93
|
class_option :pundit, default: nil
|
94
|
+
class_option :pundit_policy_override, default: nil
|
94
95
|
class_option :related_sets, default: ''
|
95
96
|
class_option :code_before_create, default: nil
|
96
97
|
class_option :code_after_create, default: nil
|
@@ -357,6 +358,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
357
358
|
|
358
359
|
|
359
360
|
@pundit = options['pundit']
|
361
|
+
@pundit_policy_override = options['pundit_policy_override']
|
360
362
|
|
361
363
|
@no_nav_menu = options['no_nav_menu']
|
362
364
|
|
@@ -978,7 +980,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
978
980
|
|
979
981
|
def list_column_headings
|
980
982
|
@template_builder.list_column_headings(
|
981
|
-
col_identifier: @layout_strategy.column_classes_for_column_headings,
|
982
983
|
column_width: @layout_strategy.column_width,
|
983
984
|
singular: @singular
|
984
985
|
)
|
@@ -1442,7 +1443,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
1442
1443
|
|
1443
1444
|
def all_line_fields
|
1444
1445
|
@template_builder.all_line_fields(
|
1445
|
-
col_identifier: @layout_strategy.column_classes_for_line_fields,
|
1446
1446
|
perc_width: @layout_strategy.each_col, # undefined method `each_col'
|
1447
1447
|
layout_strategy: @layout_strategy
|
1448
1448
|
)
|
@@ -78,11 +78,12 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def index
|
81
|
-
load_all_<%= plural %>
|
82
|
-
<% if @search_fields %>
|
81
|
+
load_all_<%= plural %><% if @search_fields %>
|
83
82
|
<%= @search_fields.collect{|field_name| @columns_map[field_name.to_sym].code_to_reset_match_if_search_is_blank}.compact.join(" \n") %><% end %>
|
84
|
-
|
85
|
-
authorize @<%= plural_name %><%
|
83
|
+
<% if @pundit %><% if @pundit && !@pundit_policy_override %>
|
84
|
+
authorize @<%= plural_name %><% elsif @pundit && @pundit_policy_override %>
|
85
|
+
skip_authorization
|
86
|
+
raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.index?<% end %>
|
86
87
|
rescue Pundit::NotAuthorizedError
|
87
88
|
flash[:alert] = 'You are not authorized to perform this action.'
|
88
89
|
render 'layouts/error'<% end %>
|
@@ -92,7 +93,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
92
93
|
@<%= singular_name %> = <%= class_name %>.new<% if eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>(<%= @object_owner_sym %>: <%= @object_owner_eval %>)<% end %><% elsif @object_owner_optional && any_nested? %>
|
93
94
|
@<%= singular_name %> = <%= class_name %>.new({}.merge(<%= @nested_set.last[:singular] %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}))<% else %>
|
94
95
|
@<%= singular_name %> = <%= class_name %>.new(<% if any_nested? %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)<% end %>
|
95
|
-
<% if @pundit
|
96
|
+
<% if @pundit && !@pundit_policy_override %>
|
97
|
+
authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
|
98
|
+
skip_authorization
|
99
|
+
raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.new?<% end %><% if @pundit %>
|
96
100
|
@action = 'new'
|
97
101
|
rescue Pundit::NotAuthorizedError
|
98
102
|
flash[:alert] = 'You are not authorized to perform this action.'
|
@@ -112,7 +116,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
112
116
|
<%= creation_syntax %>
|
113
117
|
<% if @pundit %><% @related_sets.each do |key, related_set| %>
|
114
118
|
check_<%= related_set[:association_ids_method].to_s %>_permissions(modified_params, :create)<% end %><% end %>
|
115
|
-
|
119
|
+
<% if @pundit && !@pundit_policy_override %>
|
120
|
+
authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
|
121
|
+
skip_authorization
|
122
|
+
raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.create?<% end %>
|
116
123
|
<%= @code_before_create ? "\n " + @code_before_create.gsub(";", "\n") : "" %>
|
117
124
|
if @<%= singular_name %>.save<%= @code_after_create ? ("\n " + @code_after_create.gsub(";", "\n")) : ""%>
|
118
125
|
flash[:notice] = "Successfully created #{@<%= singular %>.<%= display_class %>}"
|
@@ -148,8 +155,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
148
155
|
|
149
156
|
<% end %>
|
150
157
|
<% unless @no_edit %>
|
151
|
-
def show<% if @pundit %>
|
152
|
-
authorize @<%= singular %><%
|
158
|
+
def show<% if @pundit && !@pundit_policy_override %>
|
159
|
+
authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
|
160
|
+
skip_authorization
|
161
|
+
raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.show?<% end %>
|
153
162
|
redirect_to <%= HotGlue.optionalized_ternary(namespace: @namespace,
|
154
163
|
target: @singular,
|
155
164
|
top_level: false,
|
@@ -160,8 +169,10 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
160
169
|
put_form: true).gsub("(#{singular}", "(@#{singular}") %>
|
161
170
|
end
|
162
171
|
|
163
|
-
def edit<% if @pundit
|
164
|
-
authorize @<%=
|
172
|
+
def edit<% if @pundit && !@pundit_policy_override %>
|
173
|
+
authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
|
174
|
+
skip_authorization
|
175
|
+
raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.edit?<% end %>
|
165
176
|
@action = 'edit'
|
166
177
|
render :edit<% if @pundit %>
|
167
178
|
rescue Pundit::NotAuthorizedError
|
@@ -187,15 +198,19 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
187
198
|
|
188
199
|
<% if @hawk_keys.any? %> modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
|
189
200
|
<%= controller_attachment_orig_filename_pickup_syntax %>
|
190
|
-
|
191
|
-
if @<%= singular_name %>.attributes = modified_params
|
201
|
+
<% if @pundit && !@pundit_policy_override %>
|
192
202
|
authorize @<%= singular_name %>
|
193
203
|
<%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
|
194
|
-
|
195
|
-
<% else %>
|
196
|
-
<%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
|
204
|
+
|
197
205
|
if @<%= singular_name %>.update(modified_params)
|
198
|
-
|
206
|
+
|
207
|
+
<% elsif @pundit && @pundit_policy_override %>
|
208
|
+
skip_authorization
|
209
|
+
raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.update?
|
210
|
+
if @<%= singular_name %>.update(modified_params)
|
211
|
+
<% else %>
|
212
|
+
<%= @code_before_update ? "\n " + @code_before_update.gsub(";", "\n") : "" %>
|
213
|
+
if @<%= singular_name %>.update(modified_params)<% end %>
|
199
214
|
<%= post_action_parental_updates.compact.join("\n ") %>
|
200
215
|
<%= @code_after_update ? "\n " + @code_after_update.gsub(";", "\n") : "" %>
|
201
216
|
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
@@ -216,11 +231,14 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
216
231
|
end
|
217
232
|
|
218
233
|
<% end %><% if destroy_action %> def destroy
|
219
|
-
<% if @pundit
|
234
|
+
<% if @pundit && !@pundit_policy_override %>
|
235
|
+
authorize @<%= singular %><% elsif @pundit && @pundit_policy_override %>
|
236
|
+
skip_authorization
|
237
|
+
raise Pundit::NotAuthorizedError if ! <%= @pundit_policy_override %>.destroy?<% end %>
|
220
238
|
begin
|
221
239
|
@<%=singular_name%>.destroy
|
222
240
|
flash[:notice] = '<%= singular_name.titlecase %> successfully deleted'
|
223
|
-
rescue
|
241
|
+
rescue ActiveRecordError => e
|
224
242
|
flash[:alert] = '<%= singular_name.titlecase %> could not be deleted'
|
225
243
|
end
|
226
244
|
<%= post_action_parental_updates.join("\n ") %>
|
@@ -8,30 +8,40 @@
|
|
8
8
|
<% if @big_edit %>
|
9
9
|
</div>
|
10
10
|
</div>
|
11
|
+
</div>
|
12
|
+
|
11
13
|
|
12
14
|
|
13
15
|
<% if @downnest_children.any? && @big_edit %>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
<
|
16
|
+
<div class="container" data-controller="bootstrap-tabbed-nav">
|
17
|
+
<ul class="nav nav-tabs" id="<%= singular + "_downnest_portals" %>" role="tablist">
|
18
|
+
<% @downnest_object.each_with_index do |data,index| %>
|
19
|
+
<% downnest = data[0] %>
|
20
|
+
<li class="nav-item" role="presentation">
|
21
|
+
<button class="nav-link <%= "active" if index==0 %>" id="<%= downnest %>-tab" data-bs-toggle="tab" data-bs-target="#<%= downnest %>-portal" type="button" role="tab" aria-controls="home" aria-selected="true">
|
22
|
+
<%= downnest.titlecase.pluralize %>
|
23
|
+
</button>
|
24
|
+
</li>
|
25
|
+
<% end %>
|
26
|
+
</ul>
|
27
|
+
|
28
|
+
<div class="tab-content" id="myTabContent">
|
29
|
+
<% @downnest_object.each_with_index do |data, index| %>
|
30
|
+
<% downnest = data[0] %>
|
31
|
+
<div class="tab-pane fade <%= "show active" if index==0 %>" id="<%= downnest %>-portal" role="tabpanel" aria-labelledby="<%= downnest %>-tab">
|
19
32
|
<% downnest_object = eval("#{singular_class}.reflect_on_association(:#{downnest})") %>
|
20
33
|
<% if downnest_object.nil?; raise "no relationship for downnested portal `#{downnest}` found on `#{singular_class}`; please check relationship for has_many :#{downnest}"; end; %>
|
21
34
|
<% downnest_class = downnest_object.class_name %>
|
22
35
|
<% downnest_object_name = eval("#{downnest_class}.table_name") %>
|
23
36
|
<% downnest_style = @layout_strategy.downnest_style %>
|
24
|
-
<% if @downnest_shows_headings %>
|
25
|
-
<h3>
|
26
|
-
<%= downnest_class.titlecase.pluralize %>
|
27
|
-
</h3>
|
28
|
-
<% end %>
|
29
|
-
<\%= render partial: "<%= namespace_with_trailing_dash %><%= downnest_object_name %>/list", locals: {<%= @singular %>: @<%= @singular %>, <%= downnest_object_name %>: @<%= @singular %>.<%= downnest %><% if @nested_set.any? %>, <%= @nested_set.collect{|x| "#{x[:singular]}: @#{x[:singular]}"}.join(", ") %>, nested_for: "<%= @nested_set.collect{|x| "#{x[:singular]}-" + "\#{" + "@#{x[:singular]}.id}"}.join("__") %>__<%= singular %>-#{@<%= @singular %>.id}" <% end %> } \%>
|
30
37
|
|
31
|
-
|
38
|
+
<\%= render partial: "<%= namespace_with_trailing_dash %><%= downnest_object_name %>/list", locals: {<%= @singular %>: @<%= @singular %>, <%= downnest_object_name %>: @<%= @singular %>.<%= downnest %><% if @nested_set.any? %>, <%= @nested_set.collect{|x| "#{x[:singular]}: @#{x[:singular]}"}.join(", ") %>, nested_for: "<%= @nested_set.collect{|x| "#{x[:singular]}-" + "\#{" + "@#{x[:singular]}.id}"}.join("__") %>__<%= singular %>-#{@<%= @singular %>.id}" <% end %> } \%>
|
32
39
|
</div>
|
33
40
|
<% end %>
|
34
|
-
|
41
|
+
</div>
|
42
|
+
|
35
43
|
</div>
|
36
44
|
<% end %>
|
37
45
|
|
46
|
+
|
47
|
+
<% end %>
|
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.16
|
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: 2025-03-
|
11
|
+
date: 2025-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|