hot-glue 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +52 -18
- data/app/helpers/hot_glue/controller_helper.rb +34 -26
- data/config/database.yml +4 -4
- data/lib/generators/hot_glue/markup_templates/erb.rb +15 -10
- data/lib/generators/hot_glue/scaffold_generator.rb +159 -135
- data/lib/generators/hot_glue/templates/capybara_login.rb +1 -1
- data/lib/generators/hot_glue/templates/controller.rb.erb +22 -21
- data/lib/generators/hot_glue/templates/erb/_new_button.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/_show.erb +1 -1
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +1 -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: f420219d9ff451f6fa20c743bef94003726a86c452fba51c8487f4d537d3c258
|
4
|
+
data.tar.gz: c031f7ffe2fb832a17ce13bd78051296baec30ed279de3d6b7b73c04dfdfd3c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f72f3d5376e8b2ca6c50e3a7c8044b83ed6b62b550a91d1c2e76cf6a4b33eeab882ea760f67ee744e6d8e5c844ba1019a51368325eab5d5f4de56bd2edcbd768
|
7
|
+
data.tar.gz: 3299ae7f5aff59f94b65b7fae3af98f31dc935e7aa3c3b132e41c05057ae790c1ee10e8888ef34ebe9d6e8ddf221f5dac7a3d1ce4a8261968bca2b5b59761739
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -34,7 +34,7 @@ Hot Glue generates functionality that is quick and dirty. It lets you be crafty.
|
|
34
34
|
|
35
35
|
| | |
|
36
36
|
| ------------- | ------------- |
|
37
|
-
| ![Teachable-225x225](https://user-images.githubusercontent.com/59002/147857335-a919e095-e6de-4718-8513-736d1f283a0b.png) | Now avaiale on [Teachable](https://
|
37
|
+
| ![Teachable-225x225](https://user-images.githubusercontent.com/59002/147857335-a919e095-e6de-4718-8513-736d1f283a0b.png) | Now avaiale on [Teachable](https://jfbcodes.com/courses/hot-glue-in-depth-tutorial/?utm_source=github.com&utm_campaign=github_hot_glue_readme_page) |
|
38
38
|
|
39
39
|
|
40
40
|
---
|
@@ -71,13 +71,13 @@ _If you are on Rails 6, see [LEGACY SETUP FOR RAILS 6](https://github.com/jasonf
|
|
71
71
|
|
72
72
|
## 1. Rails 7 New App
|
73
73
|
|
74
|
-
There are two ways to create new apps on Rails 7: With or
|
74
|
+
There are two ways to create new apps on Rails 7: With or Without ImportMap. These instructions prefer the **without Importmap** method using ESBuild as the bundler, but to help you choose [see this post](https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-do-i-need-importmap-rails/)
|
75
75
|
|
76
|
-
`rails new --css=bootstrap --javascript=
|
76
|
+
`rails new --css=bootstrap --javascript=esbuild --database=postgresql`
|
77
77
|
|
78
|
-
|
78
|
+
**If using JSBundling, make sure to use the new `./bin/dev` to start your server instead of the old `rails server` or else your Turbo interactions will not work correctly.**
|
79
79
|
|
80
|
-
|
80
|
+
Confirm that both Stimulus and Turbo are working.
|
81
81
|
|
82
82
|
For the quick step-by-step guide to help you confirm that both Stimulus and Turbo are working for your new JSBundling-Rails/CSSBunlding-Rails setup [see this post](https://jasonfleetwoodboldt.com/courses/stepping-up-rails/rails-7-new-app-with-js-bundling-css-bundling/).
|
83
83
|
|
@@ -149,18 +149,13 @@ https://github.com/FortAwesome/font-awesome-sass
|
|
149
149
|
|
150
150
|
|
151
151
|
## 5. Devise
|
152
|
+
!!! Warning: as of 2022-03-22, Devise is still not compatible out-of-the-box with Rails 7.
|
152
153
|
|
153
|
-
|
154
|
-
|
155
|
-
Add to your Gemfile
|
156
|
-
|
157
|
-
As of now, Devise for Rails 7 is still not released so you must use **main branch**, like so:
|
154
|
+
please see https://github.com/heartcombo/devise/issues/5478 or check this README for updated information.
|
158
155
|
|
159
|
-
`gem 'devise', branch: 'main', git: 'https://github.com/heartcombo/devise.git'`
|
160
156
|
|
161
157
|
(If you are on Rails 6, you must do ALL of the steps in the Legacy Setup steps. Be sure not to skip **Legacy Step #5** below)
|
162
158
|
|
163
|
-
For Rails 7, be sure you are on the main branch of devise above and your logins should work. (The previously necessary step of disabling turbo shown in Legacy Step #5 is no longer needed. )
|
164
159
|
|
165
160
|
You MUST run the installer FIRST or else you will put your app into a non-workable state:
|
166
161
|
```
|
@@ -478,9 +473,42 @@ In this case a controller would be generated that would have NO before_action to
|
|
478
473
|
Please note that this example would produce non-functional code, so you would need to manually fix your controllers to make sure `current_account` is available to the controller.
|
479
474
|
|
480
475
|
|
476
|
+
### `--hawk=`
|
477
|
+
|
478
|
+
Hawk a foreign key that is not the object's owner to within a specified scope.
|
479
|
+
|
480
|
+
Assuming a Pet belong_to a :human, when building an Appointments scaffold, you can hawk the `pet_id` to the current human's pets. (Whoever is the authentication object.)
|
481
|
+
|
482
|
+
`--hawk=pet_id`
|
483
|
+
|
484
|
+
This is covered in [Example #3 in the Hot Glue Tutorial](https://jfb.teachable.com/courses/hot-glue-in-depth-tutorial/lectures/38584014)
|
485
|
+
|
486
|
+
To hawk to a scope that is not the currently authenticated user, use curly braces `{...}` to specify the scope.
|
487
|
+
|
488
|
+
`--hawk=user_id{current_user.family}`
|
489
|
+
|
490
|
+
This would hawk the Appointment's `user_id` key to any users who are within the scope of the current_user's family.
|
491
|
+
|
492
|
+
This is covered in [Example #4 in the Hot Glue Tutorial](https://jfb.teachable.com/courses/hot-glue-in-depth-tutorial/lectures/38787505)
|
493
|
+
|
494
|
+
|
481
495
|
### `--plural=`
|
482
496
|
|
483
|
-
You don't need this if the pluralized version is just + "s" of the singular version.
|
497
|
+
You don't need this if the pluralized version is just + "s" of the singular version.
|
498
|
+
Only use for non-standard plurlizations, and be sure to pass it as TitleCase (as if you pluralized the model name which is non-standard for Rails)
|
499
|
+
|
500
|
+
An better alternative is to define the non-standard plurlizations globally in your app.
|
501
|
+
|
502
|
+
Make a file at `config/initializers/inflections.rb`
|
503
|
+
|
504
|
+
# Add new inflection rules using the following format
|
505
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
506
|
+
inflect.irregular 'clothing', 'clothes'
|
507
|
+
inflect.irregular 'human', 'humans'
|
508
|
+
|
509
|
+
|
510
|
+
# the standard pluralization is pretty sexist and will pluralize `human` to `humen`
|
511
|
+
end
|
484
512
|
|
485
513
|
|
486
514
|
### `--form-labels-position` (default: `after`; options are **before**, **after**, and **omit**)
|
@@ -707,10 +735,9 @@ See also setting `--form-labels-position` to control position or omit normal lab
|
|
707
735
|
|
708
736
|
### `--inline-list-labels` (before, after, omit; default: omit)
|
709
737
|
|
710
|
-
Determines if field label will appear on the LIST VIEW.
|
711
|
-
this affects the `_show` template which is rendered as a partial from the LIST view.
|
738
|
+
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.
|
712
739
|
|
713
|
-
Because the labels are already in the heading, this `omit` by default. (Use with `--no-list-heading` to omit the labels in the list heading.)
|
740
|
+
Because the labels are already in the heading, this is `omit` by default. (Use with `--no-list-heading` to omit the labels in the list heading.)
|
714
741
|
|
715
742
|
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.
|
716
743
|
|
@@ -773,13 +800,20 @@ Child portals have the headings omitted automatically (there is a heading identi
|
|
773
800
|
- Date: displayed as HTML5 date picker
|
774
801
|
- Time: displayed as HTML5 time picker
|
775
802
|
- Boolean: displayed radio buttons yes/ no
|
776
|
-
- Enum - displayed as a drop-down list (defined the enum values on your model).
|
803
|
+
- Enum - displayed as a drop-down list (defined the enum values on your model).
|
804
|
+
- For Rails 6 see https://jasonfleetwoodboldt.com/courses/stepping-up-rails/enumerated-types-in-rails-and-postgres/
|
777
805
|
- AFAIK, you must specify the enum definition both in your model and also in your database migration for both Rails 6 + Rails 7
|
778
806
|
|
779
807
|
|
780
808
|
# VERSION HISTORY
|
781
809
|
|
782
|
-
####
|
810
|
+
#### ???? - v0.5.2 - Hawked Foreign Keys
|
811
|
+
|
812
|
+
|
813
|
+
|
814
|
+
|
815
|
+
|
816
|
+
#### 2022-03-12 - v0.5.1 - Inline List Labels
|
783
817
|
|
784
818
|
`--inline-list-labels` (default: `after`; options are **before**, **after**, and **omit**)
|
785
819
|
|
@@ -1,17 +1,14 @@
|
|
1
1
|
module HotGlue
|
2
2
|
module ControllerHelper
|
3
|
-
|
4
3
|
def timezonize(tz)
|
5
4
|
tz = tz.to_i
|
6
5
|
(tz >= 0 ? "+" : "-") + sprintf('%02d',tz.abs) + ":00"
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
8
|
def datetime_field_localized(form_object, field_name, value, label, timezone = nil )
|
11
|
-
|
9
|
+
form_object.text_field(field_name, class: 'form-control',
|
12
10
|
type: 'datetime-local',
|
13
|
-
value: date_to_current_timezone(value, timezone))
|
14
|
-
+ timezonize(timezone)
|
11
|
+
value: date_to_current_timezone(value, timezone)) + timezonize(timezone)
|
15
12
|
end
|
16
13
|
|
17
14
|
|
@@ -24,8 +21,7 @@ module HotGlue
|
|
24
21
|
def time_field_localized(form_object, field_name, value, label, timezone = nil )
|
25
22
|
form_object.text_field(field_name, class: 'form-control',
|
26
23
|
type: 'time',
|
27
|
-
value: date_to_current_timezone(value, timezone))
|
28
|
-
+ timezonize(timezone)
|
24
|
+
value: date_to_current_timezone(value, timezone)) + timezonize(timezone)
|
29
25
|
|
30
26
|
end
|
31
27
|
|
@@ -36,40 +32,30 @@ module HotGlue
|
|
36
32
|
else
|
37
33
|
server_timezone
|
38
34
|
end
|
39
|
-
elsif true
|
40
|
-
server_timezone
|
41
|
-
# elsif defined?(controller) == "method"
|
42
|
-
# # controller.try(:current_timezone)
|
43
|
-
# elsif self.class.ancestors.include?(ApplicationController)
|
44
|
-
# self.try(:current_timezone)
|
45
35
|
else
|
46
|
-
|
47
|
-
exit
|
36
|
+
server_timezone
|
48
37
|
end
|
49
38
|
end
|
50
39
|
|
51
|
-
def server_timezone
|
52
|
-
Time.now.strftime("%z").to_i/100
|
53
|
-
end
|
54
|
-
|
55
40
|
def date_to_current_timezone(date, timezone = nil)
|
56
41
|
# if the timezone is nil, use the server date'
|
42
|
+
|
57
43
|
if timezone.nil?
|
58
44
|
timezone = Time.now.strftime("%z").to_i/100
|
59
45
|
end
|
60
46
|
|
61
47
|
return nil if date.nil?
|
62
48
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
49
|
+
return date.in_time_zone(timezone).strftime("%Y-%m-%dT%H:%M")
|
50
|
+
# begin
|
51
|
+
#
|
52
|
+
# rescue
|
53
|
+
# return nil
|
54
|
+
# end
|
68
55
|
end
|
69
56
|
|
70
|
-
|
71
|
-
|
72
57
|
def modify_date_inputs_on_params(modified_params, current_user_object = nil)
|
58
|
+
|
73
59
|
use_timezone = (current_user_object.try(:timezone)) || Time.now.strftime("%z")
|
74
60
|
|
75
61
|
modified_params = modified_params.tap do |params|
|
@@ -86,5 +72,27 @@ module HotGlue
|
|
86
72
|
end
|
87
73
|
modified_params
|
88
74
|
end
|
75
|
+
|
76
|
+
|
77
|
+
def hawk_params(hawk_schema, modified_params)
|
78
|
+
@hawk_alarm = ""
|
79
|
+
hawk_schema.each do |hawk_key,hawk_definition|
|
80
|
+
hawk_root = hawk_definition[0]
|
81
|
+
hawk_scope = hawk_definition[1]
|
82
|
+
begin
|
83
|
+
eval("hawk_root.#{hawk_scope}").find(modified_params[hawk_key.to_s])
|
84
|
+
rescue ActiveRecord::RecordNotFound => e
|
85
|
+
@hawk_alarm << "You aren't allowed to set #{hawk_key.to_s} to #{modified_params[hawk_key.to_s]}. "
|
86
|
+
modified_params.tap { |hs| hs.delete(hawk_key.to_s) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
modified_params
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def server_timezone
|
95
|
+
Time.now.strftime("%z").to_i/100
|
96
|
+
end
|
89
97
|
end
|
90
98
|
end
|
data/config/database.yml
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
development:
|
2
|
-
adapter:
|
3
|
-
database:
|
2
|
+
adapter: postgresql
|
3
|
+
database: dummy_dev
|
4
4
|
pool: 5
|
5
5
|
timeout: 5000
|
6
6
|
|
7
7
|
test:
|
8
|
-
adapter:
|
9
|
-
database:
|
8
|
+
adapter: postgresql
|
9
|
+
database: dummy_test
|
10
10
|
pool: 5
|
11
11
|
timeout: 5000
|
@@ -7,7 +7,9 @@ module HotGlue
|
|
7
7
|
:ownership_field, :form_labels_position,
|
8
8
|
:inline_list_labels,
|
9
9
|
:columns, :column_width, :col_identifier, :singular,
|
10
|
-
:form_placeholder_labels
|
10
|
+
:form_placeholder_labels, :hawk_keys
|
11
|
+
|
12
|
+
|
11
13
|
|
12
14
|
def add_spaces_each_line(text, num_spaces)
|
13
15
|
add_spaces = " " * num_spaces
|
@@ -30,8 +32,6 @@ module HotGlue
|
|
30
32
|
}.join("\n")
|
31
33
|
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
35
|
def list_column_headings(*args)
|
36
36
|
@columns = args[0][:columns]
|
37
37
|
@column_width = args[0][:column_width]
|
@@ -63,6 +63,7 @@ module HotGlue
|
|
63
63
|
@ownership_field = args[0][:ownership_field]
|
64
64
|
@form_labels_position = args[0][:form_labels_position]
|
65
65
|
@form_placeholder_labels = args[0][:form_placeholder_labels]
|
66
|
+
@hawk_keys = args[0][:hawk_keys]
|
66
67
|
|
67
68
|
@singular = args[0][:singular]
|
68
69
|
singular = @singular
|
@@ -71,7 +72,7 @@ module HotGlue
|
|
71
72
|
column.map { |col|
|
72
73
|
field_result =
|
73
74
|
if show_only.include?(col.to_sym)
|
74
|
-
"<%=
|
75
|
+
"<%= #{singular}.#{col} %>"
|
75
76
|
else
|
76
77
|
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
77
78
|
limit = eval("#{singular_class}.columns_hash['#{col}']").limit
|
@@ -132,18 +133,22 @@ module HotGlue
|
|
132
133
|
assoc_class_name = assoc.active_record.name
|
133
134
|
display_column = HotGlue.derrive_reference_name(assoc_class_name)
|
134
135
|
|
136
|
+
if @hawk_keys[assoc.foreign_key.to_sym]
|
137
|
+
hawk_definition = @hawk_keys[assoc.foreign_key.to_sym]
|
138
|
+
hawk_root = hawk_definition[0]
|
139
|
+
hawk_scope = hawk_definition[1]
|
140
|
+
hawked_association = "#{hawk_root}.#{hawk_scope}"
|
141
|
+
else
|
142
|
+
hawked_association = "#{assoc.class_name}.all"
|
143
|
+
end
|
144
|
+
|
135
145
|
(is_owner ? "<% unless @#{assoc_name} %>\n" : "") +
|
136
|
-
" <%= f.collection_select(:#{col}, #{
|
146
|
+
" <%= f.collection_select(:#{col}, #{hawked_association}, :id, :#{display_column}, {prompt: true, selected: @#{singular}.#{col} }, class: 'form-control') %>\n" +
|
137
147
|
(is_owner ? "<% else %>\n <%= @#{assoc_name}.#{display_column} %>" : "") +
|
138
148
|
(is_owner ? "\n<% end %>" : "")
|
139
149
|
|
140
150
|
else
|
141
151
|
" <%= f.text_field :#{col}, value: #{@singular}.#{col}, autocomplete: 'off', size: 4, class: 'form-control', type: 'number'" + (@form_placeholder_labels ? ", placeholder: '#{col.to_s.humanize}'" : "") + " %>\n " + "\n"
|
142
|
-
|
143
|
-
# field_output(col, nil, 4, col_identifier)
|
144
|
-
#
|
145
|
-
# # "<%= f.text_field :#{col}, value: #{singular}.#{col}, class: 'form-control', size: 4, type: 'number' %>"
|
146
|
-
|
147
152
|
end
|
148
153
|
end
|
149
154
|
|
@@ -68,19 +68,18 @@ module HotGlue
|
|
68
68
|
def self.derrive_reference_name(thing_as_string)
|
69
69
|
assoc_class = eval(thing_as_string)
|
70
70
|
|
71
|
-
if assoc_class.respond_to?("name")
|
71
|
+
if assoc_class.new.respond_to?("name")
|
72
72
|
display_column = "name"
|
73
|
-
elsif assoc_class.respond_to?("to_label")
|
73
|
+
elsif assoc_class.new.respond_to?("to_label")
|
74
74
|
display_column = "to_label"
|
75
|
-
elsif assoc_class.respond_to?("full_name")
|
75
|
+
elsif assoc_class.new.respond_to?("full_name")
|
76
76
|
display_column = "full_name"
|
77
|
-
elsif assoc_class.respond_to?("display_name")
|
77
|
+
elsif assoc_class.new.respond_to?("display_name")
|
78
78
|
display_column = "display_name"
|
79
|
-
elsif assoc_class.respond_to?("email")
|
79
|
+
elsif assoc_class.new.respond_to?("email")
|
80
80
|
display_column = "email"
|
81
|
-
else
|
82
|
-
|
83
|
-
# puts "*** Oops: Can't find any column to use as the display label for the #{assoc.name.to_s} association on the #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, or 5) email directly on your #{assoc.class_name} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
|
81
|
+
# else # SHOULD BE UNREACHABLE
|
82
|
+
# raise("this should have been caught by the checker in the initializer")
|
84
83
|
end
|
85
84
|
display_column
|
86
85
|
end
|
@@ -123,6 +122,7 @@ module HotGlue
|
|
123
122
|
class_option :smart_layout, type: :boolean, default: false
|
124
123
|
class_option :markup, type: :string, default: nil # deprecated -- use in app config instead
|
125
124
|
class_option :layout, type: :string, default: nil # if used here it will override what is in the config
|
125
|
+
class_option :hawk, type: :string, default: nil #
|
126
126
|
|
127
127
|
class_option :no_list_label, type: :boolean, default: false
|
128
128
|
|
@@ -149,8 +149,9 @@ module HotGlue
|
|
149
149
|
raise(HotGlue::Error, message)
|
150
150
|
end
|
151
151
|
|
152
|
-
|
153
|
-
|
152
|
+
|
153
|
+
if options['specs_only'] && options['no_specs']
|
154
|
+
raise(HotGlue::Error, "*** Oops: You seem to have specified both the --specs-only flag and --no-specs flags. this doesn't make any sense, so I am aborting. Aborting.")
|
154
155
|
end
|
155
156
|
|
156
157
|
if !options['exclude'].empty? && !options['include'].empty?
|
@@ -162,20 +163,16 @@ module HotGlue
|
|
162
163
|
|
163
164
|
|
164
165
|
if @stimulus_syntax.nil?
|
165
|
-
|
166
|
-
@stimulus_syntax = true
|
167
|
-
else
|
168
|
-
@stimulus_syntax = false
|
169
|
-
end
|
170
|
-
end
|
166
|
+
@stimulus_syntax = true
|
171
167
|
|
172
|
-
|
173
|
-
|
174
|
-
|
168
|
+
# if Rails.version.split(".")[0].to_i >= 7
|
169
|
+
# @stimulus_syntax = true
|
170
|
+
# else
|
171
|
+
# end
|
175
172
|
end
|
176
173
|
|
177
174
|
if !options['markup'].nil?
|
178
|
-
message = "Using --
|
175
|
+
message = "Using --markup flag in the generator is deprecated; instead, use a file at config/hot_glue.yml with a key markup set to `erb` or `haml`"
|
179
176
|
raise(HotGlue::Error, message)
|
180
177
|
end
|
181
178
|
|
@@ -185,12 +182,10 @@ module HotGlue
|
|
185
182
|
if @markup == "erb"
|
186
183
|
@template_builder = HotGlue::ErbTemplate.new
|
187
184
|
elsif @markup == "slim"
|
188
|
-
|
189
|
-
raise(HotGlue::Error, message)
|
190
|
-
@template_builder = HotGlue::SlimTemplate.new
|
191
|
-
|
185
|
+
raise(HotGlue::Error, "SLIM IS NOT IMPLEMENTED")
|
192
186
|
elsif @markup == "haml"
|
193
|
-
|
187
|
+
raise(HotGlue::Error, "HAML IS NOT IMPLEMENTED")
|
188
|
+
|
194
189
|
end
|
195
190
|
|
196
191
|
|
@@ -225,7 +220,7 @@ module HotGlue
|
|
225
220
|
@controller_build_folder_singular = singular
|
226
221
|
|
227
222
|
if ! @controller_build_folder.ends_with?("s")
|
228
|
-
raise "can't build with controller name #{@controller_build_folder} because it doesn't end with an 's'"
|
223
|
+
raise HotGlue::Error, "can't build with controller name #{@controller_build_folder} because it doesn't end with an 's'"
|
229
224
|
end
|
230
225
|
|
231
226
|
@auth = options['auth'] || "current_user"
|
@@ -234,7 +229,7 @@ module HotGlue
|
|
234
229
|
|
235
230
|
|
236
231
|
if options['nest']
|
237
|
-
raise "STOP: the flag --nest has been replaced with --nested; please re-run using the --nested flag"
|
232
|
+
raise HotGlue::Error, "STOP: the flag --nest has been replaced with --nested; please re-run using the --nested flag"
|
238
233
|
|
239
234
|
end
|
240
235
|
|
@@ -275,7 +270,8 @@ module HotGlue
|
|
275
270
|
|
276
271
|
@form_labels_position = options['form_labels_position']
|
277
272
|
if !['before','after','omit'].include?(@form_labels_position)
|
278
|
-
|
273
|
+
|
274
|
+
raise HotGlue::Error, "You passed '#{@form_labels_position}' as the setting for --form-labels-position but the only allowed options are before, after (default), and omit"
|
279
275
|
end
|
280
276
|
|
281
277
|
@form_placeholder_labels = options['form_placeholder_labels'] # true or false
|
@@ -283,7 +279,7 @@ module HotGlue
|
|
283
279
|
|
284
280
|
|
285
281
|
if !['before','after','omit'].include?(@inline_list_labels)
|
286
|
-
raise "You passed '#{@inline_list_labels}' as the setting for --inline-list-labels but the only allowed options are before, after, and omit (default)"
|
282
|
+
raise HotGlue::Error, "You passed '#{@inline_list_labels}' as the setting for --inline-list-labels but the only allowed options are before, after, and omit (default)"
|
287
283
|
end
|
288
284
|
|
289
285
|
|
@@ -292,7 +288,7 @@ module HotGlue
|
|
292
288
|
@smart_layout = options['smart_layout']
|
293
289
|
|
294
290
|
if options['include'].include?(":") && @smart_layout
|
295
|
-
raise "You specified both --smart-layout and also specified grouping mode (there is a : character in your field include list); you must remove the colon(s) from your --include tag or remove the --smart-layout option"
|
291
|
+
raise HotGlue::Error, "You specified both --smart-layout and also specified grouping mode (there is a : character in your field include list); you must remove the colon(s) from your --include tag or remove the --smart-layout option"
|
296
292
|
end
|
297
293
|
|
298
294
|
|
@@ -320,9 +316,24 @@ module HotGlue
|
|
320
316
|
raise "This controller appears to be the same as the authentication object but in this context you cannot build a new/create action; please re-run with --no-create flag"
|
321
317
|
end
|
322
318
|
|
323
|
-
|
324
|
-
|
319
|
+
@magic_buttons = []
|
320
|
+
if options['magic_buttons']
|
321
|
+
@magic_buttons = options['magic_buttons'].split(',')
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
@small_buttons = options['small_buttons'] || false
|
326
|
+
|
327
|
+
@build_update_action = !@no_edit || !@magic_buttons.empty?
|
328
|
+
# if the magic buttons are present, build the update action anyway
|
329
|
+
|
330
|
+
@ujs_syntax = options['ujs_syntax']
|
331
|
+
if !@ujs_syntax
|
332
|
+
@ujs_syntax = !defined?(Turbo::Engine)
|
333
|
+
end
|
334
|
+
|
325
335
|
|
336
|
+
# NEST CHAIN
|
326
337
|
# new syntax
|
327
338
|
# @nested_set = [
|
328
339
|
# {
|
@@ -333,10 +344,6 @@ module HotGlue
|
|
333
344
|
@nested_set = []
|
334
345
|
|
335
346
|
if ! @nested.nil?
|
336
|
-
|
337
|
-
|
338
|
-
@nested_args = @nested.split("/").collect{|x| x.gsub("~","")}
|
339
|
-
|
340
347
|
@nested_set = @nested.split("/").collect { |arg|
|
341
348
|
is_optional = arg.start_with?("~")
|
342
349
|
arg.gsub!("~","")
|
@@ -347,57 +354,51 @@ module HotGlue
|
|
347
354
|
}
|
348
355
|
|
349
356
|
}
|
350
|
-
|
351
|
-
puts "@nested_set is #{@nested_set}"
|
352
|
-
@nested_args_plural = {}
|
353
|
-
|
354
|
-
|
355
|
-
@nested_args.each do |a|
|
356
|
-
@nested_args_plural[a] = a + "s"
|
357
|
-
end
|
357
|
+
puts "NESTING: #{@nested_set}"
|
358
358
|
end
|
359
359
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
@build_update_action = !@no_edit || !@magic_buttons.empty?
|
369
|
-
# if the magic buttons are present, build the update action anyway
|
360
|
+
# OBJECT OWNERSHIP & NESTING
|
361
|
+
@reference_name = HotGlue.derrive_reference_name(singular_class)
|
362
|
+
if @auth && @self_auth
|
363
|
+
# byebug
|
364
|
+
@object_owner_sym = @auth.gsub("current_", "").to_sym
|
365
|
+
@object_owner_eval = @auth
|
366
|
+
@object_owner_optional = false
|
367
|
+
@object_owner_name = @auth.gsub("current_", "").to_s
|
370
368
|
|
371
369
|
|
372
|
-
|
370
|
+
elsif @auth && ! @self_auth && @nested_set.none? && !@auth.include?(".")
|
371
|
+
# byebug
|
373
372
|
@object_owner_sym = @auth.gsub("current_", "").to_sym
|
374
373
|
@object_owner_eval = @auth
|
375
374
|
@object_owner_optional = false
|
376
|
-
|
375
|
+
@object_owner_name = @auth.gsub("current_", "").to_s
|
377
376
|
|
378
|
-
|
377
|
+
elsif @auth && @auth.include?(".")
|
378
|
+
# byebug
|
379
|
+
@object_owner_sym = nil
|
380
|
+
@object_owner_eval = @auth
|
381
|
+
else
|
382
|
+
# byebug
|
383
|
+
if @nested_set.any?
|
379
384
|
@object_owner_sym = @nested_set.last[:singular].to_sym
|
380
385
|
@object_owner_eval = "@#{@nested_set.last[:singular]}"
|
381
386
|
@object_owner_name = @nested_set.last[:singular]
|
382
387
|
@object_owner_optional = @nested_set.last[:optional]
|
383
388
|
else
|
384
|
-
@object_owner_sym =
|
389
|
+
@object_owner_sym = nil
|
385
390
|
@object_owner_eval = ""
|
386
391
|
end
|
387
392
|
end
|
388
393
|
|
394
|
+
identify_object_owner
|
395
|
+
setup_hawk_keys
|
389
396
|
|
390
|
-
@ujs_syntax = options['ujs_syntax']
|
391
397
|
|
392
|
-
if !@ujs_syntax
|
393
|
-
@ujs_syntax = !defined?(Turbo::Engine)
|
394
|
-
end
|
395
|
-
@reference_name = HotGlue.derrive_reference_name(singular_class)
|
396
398
|
|
397
|
-
|
399
|
+
# SETUP FIELDS & LAYOUT
|
398
400
|
setup_fields
|
399
|
-
|
400
|
-
if (@columns - @show_only - (@object_owner_sym.empty? ? [] : [@ownership_field.to_sym])).empty?
|
401
|
+
if (@columns - @show_only - (@ownership_field ? [@ownership_field.to_sym] : [])).empty?
|
401
402
|
@no_field_form = true
|
402
403
|
end
|
403
404
|
|
@@ -412,41 +413,61 @@ module HotGlue
|
|
412
413
|
})
|
413
414
|
@layout_object = builder.construct
|
414
415
|
|
415
|
-
@menu_file_exists = true if @
|
416
|
+
@menu_file_exists = true if @nested_set.none? && File.exists?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
|
417
|
+
|
416
418
|
|
417
419
|
end
|
418
420
|
|
421
|
+
def setup_hawk_keys
|
422
|
+
@hawk_keys = {}
|
423
|
+
|
424
|
+
if options['hawk']
|
425
|
+
options['hawk'].split(",").each do |hawk_entry|
|
426
|
+
# format is: abc_id[thing]
|
427
|
+
|
428
|
+
if hawk_entry.include?("{")
|
429
|
+
hawk_entry =~ /(.*){(.*)}/
|
430
|
+
key, hawk_to = $1, $2
|
431
|
+
else
|
432
|
+
key = hawk_entry
|
433
|
+
hawk_to = @auth
|
434
|
+
end
|
435
|
+
hawk_scope = key.gsub("_id", "").pluralize
|
436
|
+
@hawk_keys[key.to_sym] = [hawk_to, hawk_scope]
|
437
|
+
end
|
438
|
+
|
439
|
+
puts "HAWKING: #{@hawk_keys}"
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
419
443
|
def identify_object_owner
|
420
444
|
auth_assoc = @auth && @auth.gsub("current_","")
|
421
445
|
|
422
|
-
if
|
446
|
+
if @object_owner_sym && ! @self_auth
|
423
447
|
auth_assoc_field = auth_assoc + "_id" unless @god
|
424
|
-
|
425
448
|
assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
|
426
|
-
|
449
|
+
# byebug
|
427
450
|
if assoc
|
428
451
|
@ownership_field = assoc.name.to_s + "_id"
|
429
|
-
elsif ! @
|
430
|
-
|
431
|
-
exit_message = "*** Oops: It looks like is no association from class called #{@singular_class} to the current_#{@object_owner_sym}. If your user is called something else, pass with flag auth=current_X where X is the model for your users as lowercase. Also, be sure to implement current_X as a method on your controller. (If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for auth_identifier.) To make a controller that can read all records, specify with --god."
|
452
|
+
elsif ! @nested_set.any?
|
453
|
+
exit_message = "*** Oops: It looks like is no association `#{@object_owner_sym}` from the object #{@singular_class}. If your user is called something else, pass with flag auth=current_X where X is the model for your users as lowercase. Also, be sure to implement current_X as a method on your controller. (If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for auth_identifier.) To make a controller that can read all records, specify with --god."
|
432
454
|
raise(HotGlue::Error, exit_message)
|
433
455
|
|
434
456
|
else
|
435
|
-
|
436
457
|
if eval(singular_class + ".reflect_on_association(:#{@object_owner_sym.to_s})").nil? && !eval(singular_class + ".reflect_on_association(:#{@object_owner_sym.to_s.singularize})").nil?
|
437
458
|
exit_message = "*** Oops: you tried to nest #{singular_class} within a route for `#{@object_owner_sym}` but I can't find an association for this relationship. Did you mean `#{@object_owner_sym.to_s.singularize}` (singular) instead?"
|
438
|
-
else
|
439
|
-
|
459
|
+
# else # NOTE: not reachable
|
460
|
+
# exit_message = "*** Oops: Missing relationship from class #{singular_class} to :#{@object_owner_sym} maybe add `belongs_to :#{@object_owner_sym}` to #{singular_class}\n (If your user is called something else, pass with flag auth=current_X where X is the model for your auth object as lowercase. Also, be sure to implement current_X as a method on your controller. If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for --auth-identifier flag). To make a controller that can read all records, specify with --god."
|
440
461
|
end
|
441
462
|
|
442
463
|
raise(HotGlue::Error, exit_message)
|
443
464
|
end
|
465
|
+
elsif @object_owner_sym && ! @object_owner_eval.include?(".")
|
466
|
+
@ownership_field = @object_owner_name + "_id"
|
444
467
|
end
|
445
468
|
end
|
446
469
|
|
447
|
-
|
448
470
|
def setup_fields
|
449
|
-
auth_assoc = @auth && @auth.gsub("current_","")
|
450
471
|
|
451
472
|
if !@include_fields
|
452
473
|
@exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
|
@@ -455,7 +476,6 @@ module HotGlue
|
|
455
476
|
:confirmation_token, :confirmed_at,
|
456
477
|
:confirmation_sent_at, :unconfirmed_email
|
457
478
|
|
458
|
-
@exclude_fields.push( (auth_assoc + "_id").to_sym) if ! auth_assoc.nil?
|
459
479
|
@exclude_fields.push( @ownership_field.to_sym ) if ! @ownership_field.nil?
|
460
480
|
|
461
481
|
|
@@ -477,30 +497,34 @@ module HotGlue
|
|
477
497
|
assoc_name = col.to_s.gsub("_id","")
|
478
498
|
|
479
499
|
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
exit_message = "*** Oops: The model #{singular_class} is missing an association for :#{assoc_name} or the model #{assoc_name.titlecase} doesn't exist. TODO: Please implement a model for #{assoc_name.titlecase};
|
500
|
+
assoc_model = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
501
|
+
|
502
|
+
if assoc_model.nil?
|
503
|
+
exit_message = "*** Oops: The model #{singular_class} is missing an association for :#{assoc_name} or the model #{assoc_name.titlecase} doesn't exist. TODO: Please implement a model for #{assoc_name.titlecase}; or add to #{singular_class} `belongs_to :#{assoc_name}`. To make a controller that can read all records, specify with --god."
|
484
504
|
puts exit_message
|
485
505
|
raise(HotGlue::Error, exit_message)
|
486
506
|
end
|
487
507
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
508
|
+
begin
|
509
|
+
assoc_class = eval(assoc_model.try(:class_name))
|
510
|
+
@associations << assoc_name.to_sym
|
511
|
+
name_list = [:name, :to_label, :full_name, :display_name, :email]
|
512
|
+
|
513
|
+
rescue
|
514
|
+
# unreachable(?)
|
515
|
+
# if eval("#{singular_class}.reflect_on_association(:#{assoc_name.singularize})")
|
516
|
+
# raise(HotGlue::Error,"*** Oops: #{singular_class} has no association for #{assoc_name.singularize}")
|
517
|
+
# else
|
518
|
+
# raise(HotGlue::Error,"*** Oops: Missing relationship from class #{singular_class} to :#{@object_owner_sym} maybe add `belongs_to :#{@object_owner_sym}` to #{singular_class}\n (If your user is called something else, pass with flag auth=current_X where X is the model for your auth object as lowercase. Also, be sure to implement current_X as a method on your controller. If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for --auth-identifier flag). To make a controller that can read all records, specify with --god.")
|
519
|
+
# end
|
493
520
|
end
|
494
521
|
|
495
|
-
|
496
|
-
assoc_class = eval(assoc_model.name)
|
497
|
-
name_list = [:name, :to_label, :full_name, :display_name, :email]
|
498
|
-
if name_list.collect{ |field|
|
522
|
+
if assoc_class && name_list.collect{ |field|
|
499
523
|
assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
|
500
524
|
}.any?
|
501
525
|
# do nothing here
|
502
526
|
else
|
503
|
-
exit_message = "
|
527
|
+
exit_message = "Oops: Missing a label for `#{assoc_class}`. Can't find any column to use as the display label for the #{assoc_name} association on the #{singular_class} model. TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name 5) email. You can implement any of these directly on your`#{assoc_class}` model (can be database fields or model methods) or alias them to field you want to use as your display label. Then RERUN THIS GENERATOR. (Field used will be chosen based on rank here.)"
|
504
528
|
raise(HotGlue::Error,exit_message)
|
505
529
|
end
|
506
530
|
end
|
@@ -508,6 +532,11 @@ module HotGlue
|
|
508
532
|
end
|
509
533
|
end
|
510
534
|
|
535
|
+
|
536
|
+
def auth_root
|
537
|
+
"authenticate_" + @auth_identifier.split(".")[0] + "!"
|
538
|
+
end
|
539
|
+
|
511
540
|
def formats
|
512
541
|
[format]
|
513
542
|
end
|
@@ -523,7 +552,7 @@ module HotGlue
|
|
523
552
|
if @namespace
|
524
553
|
begin
|
525
554
|
eval(controller_descends_from)
|
526
|
-
puts " skipping base controller #{controller_descends_from}"
|
555
|
+
# puts " skipping base controller #{controller_descends_from}"
|
527
556
|
rescue NameError => e
|
528
557
|
template "base_controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "base_controller.rb")
|
529
558
|
end
|
@@ -590,8 +619,8 @@ module HotGlue
|
|
590
619
|
end
|
591
620
|
|
592
621
|
def object_parent_mapping_as_argument_for_specs
|
593
|
-
if @
|
594
|
-
", " + @
|
622
|
+
if @nested_set.any?
|
623
|
+
", " + @nested_set.last[:singular] + ": " + @nested_set.last[:singular]
|
595
624
|
elsif @auth
|
596
625
|
", #{@auth_identifier}: #{@auth}"
|
597
626
|
end
|
@@ -603,21 +632,19 @@ module HotGlue
|
|
603
632
|
last_parent = ", #{@auth_identifier}: #{@auth}"
|
604
633
|
end
|
605
634
|
|
606
|
-
@
|
607
|
-
res << " let(:#{arg}) {create(:#{arg} #{last_parent} )}\n"
|
608
|
-
last_parent = ", #{arg}: #{arg}"
|
635
|
+
@nested_set.each do |arg|
|
636
|
+
res << " let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
|
637
|
+
last_parent = ", #{arg[:singular]}: #{arg[:singular]}"
|
609
638
|
end
|
610
639
|
res
|
611
640
|
end
|
612
641
|
|
613
|
-
|
614
642
|
def objest_nest_params_by_id_for_specs
|
615
|
-
@
|
616
|
-
"#{arg}_id: #{arg}.id"
|
643
|
+
@nested_set.map{|arg|
|
644
|
+
"#{arg[:singular]}_id: #{arg[:singular]}.id"
|
617
645
|
}.join(",\n ")
|
618
646
|
end
|
619
647
|
|
620
|
-
|
621
648
|
def controller_class_name
|
622
649
|
@controller_build_name
|
623
650
|
end
|
@@ -639,8 +666,8 @@ module HotGlue
|
|
639
666
|
end
|
640
667
|
|
641
668
|
def path_helper_args
|
642
|
-
if @
|
643
|
-
[(@
|
669
|
+
if @nested_set.any? && @nested
|
670
|
+
[(@nested_set).collect{|a| "#{a[:singular]}"} , singular].join(",")
|
644
671
|
else
|
645
672
|
singular
|
646
673
|
end
|
@@ -648,7 +675,7 @@ module HotGlue
|
|
648
675
|
|
649
676
|
def path_helper_singular
|
650
677
|
if @nested
|
651
|
-
"#{@namespace+"_" if @namespace}#{(@
|
678
|
+
"#{@namespace+"_" if @namespace}#{(@nested_set.collect{|x| x[:singular]}.join("_") + "_" if @nested_set.any?)}#{@controller_build_folder_singular}_path"
|
652
679
|
else
|
653
680
|
"#{@namespace+"_" if @namespace}#{@controller_build_folder_singular}_path"
|
654
681
|
end
|
@@ -697,7 +724,7 @@ module HotGlue
|
|
697
724
|
|
698
725
|
def path_arity
|
699
726
|
res = ""
|
700
|
-
if @
|
727
|
+
if @nested_set.any? && @nested
|
701
728
|
res << nested_objects_arity + ", "
|
702
729
|
end
|
703
730
|
res << "@" + singular
|
@@ -716,33 +743,24 @@ module HotGlue
|
|
716
743
|
end
|
717
744
|
|
718
745
|
def new_path_name
|
719
|
-
|
720
746
|
HotGlue.optionalized_ternary(namespace: @namespace,
|
721
747
|
target: singular,
|
722
748
|
nested_set: @nested_set,
|
723
749
|
modifier: "new_",
|
724
750
|
with_params: true)
|
725
|
-
# base = "new_#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_") if @nested_args.any?}#{@controller_build_folder_singular}_path"
|
726
|
-
# if @nested_args.any?
|
727
|
-
# base += "(" + @nested_args.collect { |arg|
|
728
|
-
# "#{arg}.id"
|
729
|
-
# }.join(", ") + ")"
|
730
|
-
# end
|
731
|
-
# base
|
732
751
|
end
|
733
752
|
|
734
753
|
def nested_assignments
|
735
|
-
return "" if @
|
736
|
-
@
|
754
|
+
return "" if @nested_set.none?
|
755
|
+
@nested_set.map{|a| "#{a}: #{a}"}.join(", ") #metaprgramming into Ruby hash
|
737
756
|
end
|
738
757
|
|
739
758
|
def nested_assignments_top_level # this is by accessing the instance variable-- only use at top level
|
740
|
-
@
|
759
|
+
@nested_set.map{|a| "#{a[:singular]}"}.join(", ") #metaprgramming into Ruby hash
|
741
760
|
end
|
742
761
|
|
743
|
-
|
744
762
|
def nest_assignments_operator(top_level = false, leading_comma = false)
|
745
|
-
if @
|
763
|
+
if @nested_set.any?
|
746
764
|
"#{", " if leading_comma}#{top_level ? nested_assignments_top_level : nested_assignments }"
|
747
765
|
else
|
748
766
|
""
|
@@ -754,25 +772,25 @@ module HotGlue
|
|
754
772
|
end
|
755
773
|
|
756
774
|
def nested_objects_arity
|
757
|
-
@
|
775
|
+
@nested_set.map{|a| "@#{a[:singular]}"}.join(", ")
|
758
776
|
end
|
759
777
|
|
760
778
|
def nested_arity_for_path
|
761
|
-
[@
|
779
|
+
[@nested_set[0..-1].collect{|a| "@#{a[:singular]}"}].join(", ") #metaprgramming into arity for the Rails path helper
|
762
780
|
end
|
763
781
|
|
764
782
|
def object_scope
|
765
783
|
if @auth
|
766
|
-
if @
|
784
|
+
if @nested_set.none?
|
767
785
|
@auth + ".#{plural}"
|
768
786
|
else
|
769
|
-
"@" + @
|
787
|
+
"@" + @nested_set.last[:singular] + ".#{plural}"
|
770
788
|
end
|
771
789
|
else
|
772
|
-
if @
|
790
|
+
if @nested_set.none?
|
773
791
|
@singular_class
|
774
792
|
else
|
775
|
-
"@" + @
|
793
|
+
"@" + @nested_set.last[:singular] + ".#{plural}"
|
776
794
|
end
|
777
795
|
|
778
796
|
end
|
@@ -783,10 +801,10 @@ module HotGlue
|
|
783
801
|
if @auth
|
784
802
|
if @self_auth
|
785
803
|
@singular_class + ".where(id: #{@auth}.id)"
|
786
|
-
elsif @
|
804
|
+
elsif @nested_set.none?
|
787
805
|
@auth + ".#{plural}"
|
788
806
|
else
|
789
|
-
"@" + @
|
807
|
+
"@" + @nested_set.last[:singular] + ".#{plural}"
|
790
808
|
end
|
791
809
|
else
|
792
810
|
@singular_class + ".all"
|
@@ -794,7 +812,7 @@ module HotGlue
|
|
794
812
|
end
|
795
813
|
|
796
814
|
def any_nested?
|
797
|
-
@
|
815
|
+
@nested_set.any?
|
798
816
|
end
|
799
817
|
|
800
818
|
def all_objects_variable
|
@@ -859,7 +877,7 @@ module HotGlue
|
|
859
877
|
#
|
860
878
|
# if File.exists?(menu_file)
|
861
879
|
# # TODO: can I insert the new menu item into the menu programatically here?
|
862
|
-
# # not sure how i would
|
880
|
+
# # not sure how i would achieve this without nokogiri
|
863
881
|
#
|
864
882
|
# end
|
865
883
|
|
@@ -935,6 +953,7 @@ module HotGlue
|
|
935
953
|
show_only: @show_only,
|
936
954
|
singular_class: singular_class,
|
937
955
|
singular: singular,
|
956
|
+
hawk_keys: @hawk_keys,
|
938
957
|
col_identifier: col_identifier,
|
939
958
|
ownership_field: @ownership_field,
|
940
959
|
form_labels_position: @form_labels_position,
|
@@ -1024,9 +1043,8 @@ module HotGlue
|
|
1024
1043
|
"display_name"
|
1025
1044
|
elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
|
1026
1045
|
"email"
|
1027
|
-
elsif me.column_names.include?("number") || me.instance_methods(false).include?(:number)
|
1028
|
-
"number"
|
1029
1046
|
else
|
1047
|
+
# NOT UNREACHABLE BUT UNTESTED
|
1030
1048
|
exit_message = "*** Oops: Can't find any column to use as the display label on #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, 5) email, or 6) number directly on your #{singular_class} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
|
1031
1049
|
raise(HotGlue::Error, exit_message)
|
1032
1050
|
end
|
@@ -1106,7 +1124,7 @@ module HotGlue
|
|
1106
1124
|
def nested_for_turbo_nested_constructor(top_level = true)
|
1107
1125
|
instance_symbol = "@" if top_level
|
1108
1126
|
instance_symbol = "" if !top_level
|
1109
|
-
if @
|
1127
|
+
if @nested_set.none?
|
1110
1128
|
"\"\""
|
1111
1129
|
else
|
1112
1130
|
@nested_set.collect{|arg|
|
@@ -1118,10 +1136,10 @@ module HotGlue
|
|
1118
1136
|
def nested_for_assignments_constructor(top_level = true)
|
1119
1137
|
instance_symbol = "@" if top_level
|
1120
1138
|
instance_symbol = "" if !top_level
|
1121
|
-
if @
|
1139
|
+
if @nested_set.none?
|
1122
1140
|
""
|
1123
1141
|
else
|
1124
|
-
", \n nested_for: \"" + @
|
1142
|
+
", \n nested_for: \"" + @nested_set.collect{|a| "#{a[:singular]}-" + '#{' + instance_symbol + a[:singular] + ".id}"}.join("__") + "\""
|
1125
1143
|
end
|
1126
1144
|
end
|
1127
1145
|
|
@@ -1130,6 +1148,12 @@ module HotGlue
|
|
1130
1148
|
def cc_filename_with_extensions(name, file_format = format)
|
1131
1149
|
[name, file_format].compact.join(".")
|
1132
1150
|
end
|
1151
|
+
|
1152
|
+
def hawk_to_ruby
|
1153
|
+
@hawk_keys.collect{ |k,v|
|
1154
|
+
"#{k}: [#{v[0]}, \"#{v[1]}\"] "
|
1155
|
+
}.join(", ")
|
1156
|
+
end
|
1133
1157
|
end
|
1134
1158
|
end
|
1135
1159
|
|
@@ -2,7 +2,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
2
2
|
helper :hot_glue
|
3
3
|
include HotGlue::ControllerHelper
|
4
4
|
|
5
|
-
<% unless @auth_identifier == '' || @god %>before_action
|
5
|
+
<% unless @auth_identifier == '' || @god %>before_action :<%= auth_root %><% end %>
|
6
6
|
<% if any_nested? %><% nest_chain = [] %> <% @nested_set.each { |arg|
|
7
7
|
|
8
8
|
if auth_identifier == arg[:singular]
|
@@ -19,7 +19,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
19
19
|
<% } %><% end %>
|
20
20
|
before_action :load_<%= singular_name %>, only: [:show, :edit, :update, :destroy]
|
21
21
|
after_action -> { flash.discard }, if: -> { request.format.symbol == :turbo_stream }
|
22
|
-
<% if @
|
22
|
+
<% if @nested_set.any? %>
|
23
23
|
def <%= @nested_set[0][:singular] %><% if @god
|
24
24
|
next_object = nil
|
25
25
|
collect_objects = @nested_set.reverse.collect {|x|
|
@@ -36,9 +36,9 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
36
36
|
root_object = @auth + "." + @nested_set[0][:plural]
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
40
|
-
|
41
|
-
@<%= @nested_set[0][:singular] %> ||= <%= root_object %>.find(params[:<%= @nested_set[0][:singular] %>_id])<%= " if params.include?(:#{@nested_set[0][:singular]}_id)" if @nested_set[0][:optional] %> <% end %>
|
39
|
+
%>
|
40
|
+
<% if !@god && @nested_set[0][:singular] == @auth_identifier %>@<%= @nested_set[0][:singular] %> ||= <%= root_object %>
|
41
|
+
<% else %> @<%= @nested_set[0][:singular] %> ||= <%= root_object %>.find(params[:<%= @nested_set[0][:singular] %>_id])<%= " if params.include?(:#{@nested_set[0][:singular]}_id)" if @nested_set[0][:optional] %> <% end %>
|
42
42
|
end
|
43
43
|
<% end %><% if any_nested? %><% nest_chain = [@nested_set[0][:singular]]; this_scope = @nested_set[0][:plural]; %>
|
44
44
|
<% for index in 0..(@nested_set.count - 1) do
|
@@ -47,11 +47,12 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
47
47
|
|
48
48
|
this_scope = "#{nest_chain.last}.#{arg[:plural]}"
|
49
49
|
nest_chain << arg %>
|
50
|
+
<% unless @nested_set[0][:singular] == arg[:singular] %>
|
50
51
|
def <%= arg[:singular] %>
|
51
52
|
@<%= arg[:singular] %> ||= (<%= this_scope %>.find(params[:<%= arg[:singular] %>_id])<%= " if params.include?(:#{last_arg[:singular]}_id)" if last_arg && @god && last_arg[:optional] %>)
|
52
|
-
|
53
|
-
end<% end %>
|
54
|
-
|
53
|
+
<% if @god && last_arg && (last_arg[:optional] ) %>@<%= arg[:singular] %> ||= (<%= collect_objects[index-1] %>.find(params[:<%= arg[:singular] %>_id]) if params.include?(:<%= arg[:singular] %>_id) ) <% end %>
|
54
|
+
end<% end %>
|
55
|
+
<% end %><% end %> <% if !@self_auth %>
|
55
56
|
def load_<%= singular_name %>
|
56
57
|
@<%= singular_name %> = (<%= object_scope.gsub("@",'') %>.find(params[:id])<%= " if params.include?(:#{@nested_set.last[:singular]}_id)" if @nested_set[0] && @nested_set[0][:optional] %>)<% if @nested_set[0] && @nested_set[0][:optional] %> || <%= class_name %>.find(params[:id])<% end %>
|
57
58
|
end
|
@@ -73,8 +74,9 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
73
74
|
end
|
74
75
|
|
75
76
|
<% if create_action %> def new
|
76
|
-
<% if
|
77
|
-
@<%= singular_name %> = <%= class_name %>.new(
|
77
|
+
<% if @object_owner_sym %>
|
78
|
+
@<%= singular_name %> = <%= class_name %>.new(<% if eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)
|
79
|
+
|
78
80
|
<% elsif @object_owner_optional && any_nested? %>
|
79
81
|
@<%= singular_name %> = <%= class_name %>.new({}.merge(<%= @nested_set.last[:singular] %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {})) <% else %>
|
80
82
|
@<%= singular_name %> = <%= class_name %>.new(<% if any_nested? %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)
|
@@ -85,8 +87,8 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
85
87
|
end
|
86
88
|
|
87
89
|
def create
|
88
|
-
modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<% if
|
89
|
-
|
90
|
+
modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>.merge!(<% if @object_owner_optional && any_nested? %><%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {} <% else %> <%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>) <% end %>)
|
91
|
+
<% if @hawk_keys.any? %> modified_params = hawk_params( {<%= hawk_to_ruby %>}, modified_params)<% end %>
|
90
92
|
|
91
93
|
@<%=singular_name %> = <%= class_name %>.create(modified_params)
|
92
94
|
|
@@ -98,7 +100,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
98
100
|
format.html { redirect_to <%= path_helper_plural %> }
|
99
101
|
end
|
100
102
|
else
|
101
|
-
flash[:alert] = "Oops, your <%= singular_name %> could not be created."
|
103
|
+
flash[:alert] = "Oops, your <%= singular_name %> could not be created. #{@hawk_alarm}"
|
102
104
|
respond_to do |format|
|
103
105
|
format.turbo_stream
|
104
106
|
format.html
|
@@ -120,10 +122,13 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
120
122
|
end
|
121
123
|
|
122
124
|
<% end %><% if @build_update_action %> def update
|
123
|
-
|
125
|
+
modified_params = modify_date_inputs_on_params(<%= singular %>_params<%= @auth ? ', ' + @auth : '' %>)<%= controller_update_params_tap_away_magic_buttons %>
|
126
|
+
<% if @hawk_keys.any? %> modified_params = hawk_params( {<%= hawk_to_ruby %>}, modified_params)<% end %>
|
127
|
+
<%= controller_magic_button_update_actions %> if @<%= singular_name %>.update(modified_params)
|
124
128
|
flash[:notice] = (flash[:notice] || "") << "Saved #{@<%= singular %>.<%= display_class %>}"
|
129
|
+
flash[:alert] = @hawk_alarm if !@hawk_alarm.empty?
|
125
130
|
else
|
126
|
-
flash[:alert] = (flash[:alert] || "") << "<%= singular_name.titlecase %> could not be saved."
|
131
|
+
flash[:alert] = (flash[:alert] || "") << "<%= singular_name.titlecase %> could not be saved. #{@hawk_alarm}"
|
127
132
|
|
128
133
|
end
|
129
134
|
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
@@ -137,7 +142,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
137
142
|
begin
|
138
143
|
@<%=singular_name%>.destroy
|
139
144
|
rescue StandardError => e
|
140
|
-
flash[:alert] = "<%= singular_name.titlecase %> could not be deleted"
|
145
|
+
flash[:alert] = "<%= singular_name.titlecase %> could not be deleted."
|
141
146
|
end
|
142
147
|
load_all_<%= plural %>
|
143
148
|
respond_to do |format|
|
@@ -147,11 +152,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
147
152
|
end<% end %>
|
148
153
|
|
149
154
|
def <%=singular_name%>_params
|
150
|
-
params.require(:<%=singular_name%>).permit( <%= @columns + @magic_buttons.collect(&:to_sym) %> )
|
151
|
-
end
|
152
|
-
|
153
|
-
def default_colspan
|
154
|
-
<%= @default_colspan %>
|
155
|
+
params.require(:<%=singular_name%>).permit( <%= (@columns - @show_only) + @magic_buttons.collect(&:to_sym) %> )
|
155
156
|
end
|
156
157
|
|
157
158
|
def namespace
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<\%= turbo_frame_tag "<%= singular %>-new" do %>
|
2
2
|
<div>
|
3
|
-
<\%= link_to "New <%= thing_label %>", <%= new_path_name %>, disable_with: "Loading...", class: "new-<%= singular %>-button btn btn-primary pull-right <%= 'btn-sm' if @
|
3
|
+
<\%= link_to "New <%= thing_label %>", <%= new_path_name %>, disable_with: "Loading...", class: "new-<%= singular %>-button btn btn-primary pull-right <%= 'btn-sm' if @nested_set.any? %> " %>
|
4
4
|
</div>
|
5
5
|
<\% end %>
|
@@ -15,7 +15,7 @@
|
|
15
15
|
<%= @singular %>: <%= @singular %>,
|
16
16
|
<%= downnest_object_name %>: <%= @singular %>.<%= downnest %>
|
17
17
|
}
|
18
|
-
.merge({nested_for: "<% if @
|
18
|
+
.merge({nested_for: "<% if @nested_set.any? %>#{nested_for + "__" if defined?(nested_for)}<% end %><%= @singular %>-#{<%= @singular %>.id}"})
|
19
19
|
<%= @nested_set.collect{|arg| ".merge(defined?(#{arg[:singular]}) ? {#{arg[:singular]}: #{arg[:singular]}} : {} )"}.join("\n") %>
|
20
20
|
\%>
|
21
21
|
</div>
|
@@ -10,7 +10,7 @@ describe "interaction for <%= controller_class_name %>", type: :feature do
|
|
10
10
|
when :integer
|
11
11
|
if col.to_s.ends_with?("_id")
|
12
12
|
assoc = "#{col.to_s.gsub('_id','')}"
|
13
|
-
"let!(:#{assoc}1) {create(:#{assoc})}"
|
13
|
+
"let!(:#{assoc}1) {create(:#{assoc}" + (@hawk_keys["#{assoc}_id".to_sym] ? ", #{@auth.gsub('current_', '')}: #{@auth}": "") + ")}"
|
14
14
|
end
|
15
15
|
else
|
16
16
|
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.5.
|
4
|
+
version: 0.5.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: 2022-03-
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
148
|
- !ruby/object:Gem::Version
|
149
149
|
version: '0'
|
150
150
|
requirements: []
|
151
|
-
rubygems_version: 3.1.
|
151
|
+
rubygems_version: 3.1.4
|
152
152
|
signing_key:
|
153
153
|
specification_version: 4
|
154
154
|
summary: A gem to build Tubro Rails scaffolding.
|