hot-glue 0.5.11 → 0.5.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +17 -2
  3. data/README.md +78 -7
  4. data/lib/generators/hot_glue/default_config_loader.rb +12 -0
  5. data/lib/generators/hot_glue/field_factory.rb +2 -0
  6. data/lib/generators/hot_glue/fields/association_field.rb +1 -1
  7. data/lib/generators/hot_glue/fields/attachment_field.rb +27 -0
  8. data/lib/generators/hot_glue/fields/date_time_field.rb +3 -2
  9. data/lib/generators/hot_glue/fields/enum_field.rb +2 -2
  10. data/lib/generators/hot_glue/fields/field.rb +2 -2
  11. data/lib/generators/hot_glue/fields/integer_field.rb +1 -1
  12. data/lib/generators/hot_glue/fields/uuid_field.rb +1 -2
  13. data/lib/generators/hot_glue/flash_notices_install_generator.rb +20 -0
  14. data/lib/generators/hot_glue/hot_glue.rb +5 -0
  15. data/lib/generators/hot_glue/install_generator.rb +2 -7
  16. data/lib/generators/hot_glue/layout/builder.rb +38 -55
  17. data/lib/generators/hot_glue/markup_templates/erb.rb +9 -15
  18. data/lib/generators/hot_glue/scaffold_generator.rb +971 -1008
  19. data/lib/generators/hot_glue/templates/controller.rb.erb +5 -4
  20. data/lib/generators/hot_glue/templates/erb/_edit.erb +12 -0
  21. data/lib/generators/hot_glue/templates/erb/_flash_notices.erb +12 -8
  22. data/lib/generators/hot_glue/templates/erb/_list.erb +1 -2
  23. data/lib/generators/hot_glue/templates/erb/_show.erb +2 -2
  24. data/lib/generators/hot_glue/templates/erb/create.turbo_stream.erb +3 -4
  25. data/lib/generators/hot_glue/templates/erb/destroy.turbo_stream.erb +7 -1
  26. data/lib/generators/hot_glue/templates/erb/edit.erb +34 -16
  27. data/lib/generators/hot_glue/templates/erb/update.turbo_stream.erb +3 -6
  28. data/lib/generators/hot_glue/templates/system_spec.rb.erb +1 -1
  29. data/lib/hot-glue.rb +81 -0
  30. data/lib/hotglue/version.rb +1 -1
  31. data/script/test +2 -4
  32. metadata +6 -18
  33. data/lib/generators/hot_glue/templates/erb/_errors.erb +0 -11
  34. data/lib/generators/hot_glue/templates/haml/_errors.haml +0 -6
  35. data/lib/generators/hot_glue/templates/haml/_flash_notices.haml +0 -8
  36. data/lib/generators/hot_glue/templates/haml/_form.haml +0 -5
  37. data/lib/generators/hot_glue/templates/haml/_line.haml +0 -6
  38. data/lib/generators/hot_glue/templates/haml/_list.haml +0 -15
  39. data/lib/generators/hot_glue/templates/haml/_new_button.haml +0 -2
  40. data/lib/generators/hot_glue/templates/haml/_new_form.haml +0 -7
  41. data/lib/generators/hot_glue/templates/haml/_show.haml +0 -7
  42. data/lib/generators/hot_glue/templates/haml/create.turbo_stream.haml +0 -14
  43. data/lib/generators/hot_glue/templates/haml/destroy.turbo_stream.haml +0 -2
  44. data/lib/generators/hot_glue/templates/haml/edit.haml +0 -19
  45. data/lib/generators/hot_glue/templates/haml/edit.turbo_stream.haml +0 -4
  46. data/lib/generators/hot_glue/templates/haml/index.haml +0 -8
  47. data/lib/generators/hot_glue/templates/haml/new.haml +0 -1
  48. data/lib/generators/hot_glue/templates/haml/update.turbo_stream.haml +0 -9
@@ -1,4 +1,6 @@
1
+
1
2
  require 'rails/generators/erb/scaffold/scaffold_generator'
3
+ require_relative './default_config_loader'
2
4
  require 'ffaker'
3
5
  require_relative './fields/field'
4
6
  require_relative './field_factory'
@@ -10,1225 +12,1169 @@ require_relative './layout_strategy/bootstrap'
10
12
  require_relative './layout_strategy/hot_glue'
11
13
  require_relative './layout_strategy/tailwind'
12
14
 
13
- module HotGlue
14
- class Error < StandardError
15
- end
16
-
17
- def self.construct_downnest_object(input)
18
- res = input.split(",").map { |child|
19
- child_name = child.gsub("+","")
20
- extra_size = child.count("+")
21
- {child_name => 4+extra_size}
22
- }
23
- Hash[*res.collect{|hash| hash.collect{|key,value| [key,value].flatten}.flatten}.flatten]
24
- end
25
-
26
- def self.optionalized_ternary(namespace: nil,
27
- target:,
28
- nested_set:,
29
- modifier: "",
30
- with_params: false,
31
- top_level: false,
32
- put_form: false)
33
- instance_sym = top_level ? "@" : ""
34
- if nested_set.nil? || nested_set.empty?
35
- return modifier + "#{(namespace + '_') if namespace}#{target}_path" + (("(#{instance_sym}#{target})" if put_form) || "")
36
- elsif nested_set[0][:optional] == false
37
- return modifier + ((namespace + "_" if namespace) || "") + nested_set.collect{|x|
38
- x[:singular] + "_"
39
- }.join() + target + "_path" + (("(#{nested_set.collect{
40
- |x| instance_sym + x[:singular] }.join(",")
41
- }#{ put_form ? ',' + instance_sym + target : '' })" if with_params) || "")
42
-
43
- else
44
- # copy the first item, make a ternery in this cycle, and recursively move to both the
45
- # is present path and the is optional path
46
-
47
- nonoptional = nested_set[0].dup
48
- nonoptional[:optional] = false
49
- rest_of_nest = nested_set[1..-1]
50
-
51
- is_present_path = HotGlue.optionalized_ternary(
52
- namespace: namespace,
53
- target: target,
54
- modifier: modifier,
55
- top_level: top_level,
56
- with_params: with_params,
57
- put_form: put_form,
58
- nested_set: [nonoptional, *rest_of_nest])
59
-
60
- is_missing_path = HotGlue.optionalized_ternary(
61
- namespace: namespace,
62
- target: target,
63
- modifier: modifier,
64
- top_level: top_level,
65
- with_params: with_params,
66
- put_form: put_form,
67
- nested_set: rest_of_nest )
68
- return "defined?(#{instance_sym + nested_set[0][:singular]}2) ? #{is_present_path} : #{is_missing_path}"
69
- end
70
- end
71
15
 
72
- def self.derrive_reference_name(thing_as_string)
73
- assoc_class = eval(thing_as_string)
74
16
 
75
- if assoc_class.new.respond_to?("name")
76
- display_column = "name"
77
- elsif assoc_class.new.respond_to?("to_label")
78
- display_column = "to_label"
79
- elsif assoc_class.new.respond_to?("full_name")
80
- display_column = "full_name"
81
- elsif assoc_class.new.respond_to?("display_name")
82
- display_column = "display_name"
83
- elsif assoc_class.new.respond_to?("email")
84
- display_column = "email"
85
- end
86
- display_column
87
- end
88
-
89
- class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
90
- hook_for :form_builder, :as => :scaffold
91
-
92
- source_root File.expand_path('templates', __dir__)
93
- attr_accessor :path, :singular, :plural, :singular_class, :nest_with,
94
- :columns, :downnest_children, :layout_object, :alt_lookups,
95
- :update_show_only, :hawk_keys, :auth, :sample_file_path
96
-
97
- class_option :singular, type: :string, default: nil
98
- class_option :plural, type: :string, default: nil
99
- class_option :singular_class, type: :string, default: nil
100
- class_option :nest, type: :string, default: nil # DEPRECATED —— DO NOT USE
101
- class_option :nested, type: :string, default: ""
102
-
103
- class_option :namespace, type: :string, default: nil
104
- class_option :auth, type: :string, default: nil
105
- class_option :auth_identifier, type: :string, default: nil
106
- class_option :exclude, type: :string, default: ""
107
- class_option :include, type: :string, default: ""
108
- class_option :god, type: :boolean, default: false
109
- class_option :gd, type: :boolean, default: false # alias for god
110
-
111
- class_option :specs_only, type: :boolean, default: false
112
- class_option :no_specs, type: :boolean, default: false
113
- class_option :no_delete, type: :boolean, default: false
114
- class_option :no_create, type: :boolean, default: false
115
- class_option :no_edit, type: :boolean, default: false
116
- class_option :no_list, type: :boolean, default: false
117
- class_option :no_paginate, type: :boolean, default: false
118
- class_option :big_edit, type: :boolean, default: false
119
- class_option :show_only, type: :string, default: ""
120
- class_option :update_show_only, type: :string, default: ""
121
-
122
- class_option :ujs_syntax, type: :boolean, default: nil
123
- class_option :downnest, type: :string, default: nil
124
- class_option :magic_buttons, type: :string, default: nil
125
- class_option :small_buttons, type: :boolean, default: nil
126
- class_option :display_list_after_update, type: :boolean, default: false
127
- class_option :smart_layout, type: :boolean, default: false
128
- class_option :markup, type: :string, default: nil # deprecated -- use in app config instead
129
- class_option :layout, type: :string, default: nil # if used here it will override what is in the config
130
- class_option :hawk, type: :string, default: nil
131
- class_option :with_turbo_streams, type: :boolean, default: false
132
-
133
- class_option :label, default: nil
134
- class_option :list_label_heading, default: nil
135
- class_option :new_button_label, default: nil
136
- class_option :new_form_heading, default: nil
137
-
138
- class_option :no_list_label, type: :boolean, default: false
139
- class_option :no_list_heading, type: :boolean, default: false
140
-
141
- # determines if the labels show up BEFORE or AFTER on the NEW/EDIT (form)
142
- class_option :form_labels_position, type: :string, default: 'after' # choices are before, after, omit
143
- class_option :form_placeholder_labels, type: :boolean, default: false # puts the field names into the placeholder labels
144
-
145
- # determines if labels appear within the rows of the VIEWABLE list (does NOT affect the list heading)
146
- class_option :inline_list_labels, default: 'omit' # choices are before, after, omit
147
- class_option :factory_creation, default: ''
148
- class_option :alt_foreign_key_lookup, default: '' #
149
- class_option :attachments, default: ''
150
- class_option :stacked_downnesting, default: false
151
-
152
- def initialize(*meta_args)
153
- super
17
+ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
18
+ include DefaultConfigLoader
19
+ hook_for :form_builder, :as => :scaffold
20
+
21
+ source_root File.expand_path('templates', __dir__)
22
+ attr_accessor :alt_lookups, :attachments, :auth,
23
+ :big_edit, :bootstrap_column_width,
24
+ :columns,
25
+ :downnest_children, :downnest_object,
26
+ :button_icons,
27
+ :hawk_keys, :layout_object,
28
+ :nest_with,
29
+ :path, :plural,
30
+ :sample_file_path, :singular, :singular_class, :smart_layout,
31
+ :stacked_downnesting, :update_show_only
32
+
33
+ class_option :singular, type: :string, default: nil
34
+ class_option :plural, type: :string, default: nil
35
+ class_option :singular_class, type: :string, default: nil
36
+ class_option :nest, type: :string, default: nil # DEPRECATED —— DO NOT USE
37
+ class_option :nested, type: :string, default: ""
38
+
39
+ class_option :namespace, type: :string, default: nil
40
+ class_option :auth, type: :string, default: nil
41
+ class_option :auth_identifier, type: :string, default: nil
42
+ class_option :exclude, type: :string, default: ""
43
+ class_option :include, type: :string, default: ""
44
+ class_option :god, type: :boolean, default: false
45
+ class_option :gd, type: :boolean, default: false # alias for god
46
+
47
+ class_option :specs_only, type: :boolean, default: false
48
+ class_option :no_specs, type: :boolean, default: false
49
+ class_option :no_delete, type: :boolean, default: false
50
+ class_option :no_create, type: :boolean, default: false
51
+ class_option :no_edit, type: :boolean, default: false
52
+ class_option :no_list, type: :boolean, default: false
53
+ class_option :no_paginate, type: :boolean, default: false
54
+ class_option :big_edit, type: :boolean, default: false
55
+ class_option :show_only, type: :string, default: ""
56
+ class_option :update_show_only, type: :string, default: ""
57
+
58
+ class_option :ujs_syntax, type: :boolean, default: nil
59
+ class_option :downnest, type: :string, default: nil
60
+ class_option :magic_buttons, type: :string, default: nil
61
+ class_option :small_buttons, type: :boolean, default: nil
62
+ class_option :display_list_after_update, type: :boolean, default: false
63
+ class_option :smart_layout, type: :boolean, default: false
64
+ class_option :markup, type: :string, default: nil # deprecated -- use in app config instead
65
+ class_option :layout, type: :string, default: nil # if used here it will override what is in the config
66
+ class_option :hawk, type: :string, default: nil
67
+ class_option :with_turbo_streams, type: :boolean, default: false
68
+
69
+ class_option :label, default: nil
70
+ class_option :list_label_heading, default: nil
71
+ class_option :new_button_label, default: nil
72
+ class_option :new_form_heading, default: nil
73
+
74
+ class_option :no_list_label, type: :boolean, default: false
75
+ class_option :no_list_heading, type: :boolean, default: false
76
+
77
+ # determines if the labels show up BEFORE or AFTER on the NEW/EDIT (form)
78
+ class_option :form_labels_position, type: :string, default: 'after' # choices are before, after, omit
79
+ class_option :form_placeholder_labels, type: :boolean, default: false # puts the field names into the placeholder labels
80
+
81
+ # determines if labels appear within the rows of the VIEWABLE list (does NOT affect the list heading)
82
+ class_option :inline_list_labels, default: 'omit' # choices are before, after, omit
83
+ class_option :factory_creation, default: ''
84
+ class_option :alt_foreign_key_lookup, default: '' #
85
+ class_option :attachments, default: ''
86
+ class_option :stacked_downnesting, default: false
87
+ class_option :bootstrap_column_width, default: nil #must be nil to detect if user has not passed
88
+ class_option :button_icons, default: nil
89
+
90
+ def initialize(*meta_args)
91
+ super
92
+
93
+ begin
94
+ @the_object = eval(class_name)
95
+ rescue StandardError => e
96
+ message = "*** Oops: It looks like there is no object for #{class_name}. Please define the object + database table first."
97
+ puts message
98
+ raise(HotGlue::Error, message)
99
+ end
100
+
101
+ @meta_args = meta_args
102
+
103
+ if options['specs_only'] && options['no_specs']
104
+ 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.")
105
+ end
106
+
107
+ if !options['exclude'].empty? && !options['include'].empty?
108
+ exit_message = "*** Oops: You seem to have specified both --include and --exclude. Please use one or the other. Aborting."
109
+ puts exit_message
110
+
111
+ raise(HotGlue::Error, exit_message)
112
+ end
113
+
114
+
115
+ if @stimulus_syntax.nil?
116
+ @stimulus_syntax = true
117
+ end
118
+
119
+ if !options['markup'].nil?
120
+ 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`"
121
+ raise(HotGlue::Error, message)
122
+ end
123
+
124
+ @markup = get_default_from_config(key: :markup)
125
+ @sample_file_path = get_default_from_config(key: :sample_file_path)
126
+ @bootstrap_column_width ||= get_default_from_config(key: :bootstrap_column_width) || 2
127
+
128
+ if options['layout']
129
+ layout = options['layout']
130
+ else
131
+ layout = get_default_from_config(key: :layout)
154
132
 
155
- begin
156
- @the_object = eval(class_name)
157
- rescue StandardError => e
158
- message = "*** Oops: It looks like there is no object for #{class_name}. Please define the object + database table first."
159
- puts message
160
- raise(HotGlue::Error, message)
133
+ if !['hotglue', 'bootstrap', 'tailwind'].include? layout
134
+ raise "Invalid option #{layout} in Hot glue config (config/hot_glue.yml). You must either use --layout= when generating or have a file config/hotglue.yml; specify layout as either 'hotglue' or 'bootstrap'"
161
135
  end
136
+ end
162
137
 
163
- @meta_args = meta_args
138
+ @button_icons = get_default_from_config(key: :button_icons) || 'none'
164
139
 
165
- if options['specs_only'] && options['no_specs']
166
- 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.")
140
+ @layout_strategy =
141
+ case layout
142
+ when 'bootstrap'
143
+ LayoutStrategy::Bootstrap.new(self)
144
+ when 'tailwind'
145
+ LayoutStrategy::Tailwind.new(self)
146
+ when 'hotglue'
147
+ LayoutStrategy::HotGlue.new(self)
167
148
  end
168
149
 
169
- if !options['exclude'].empty? && !options['include'].empty?
170
- exit_message = "*** Oops: You seem to have specified both --include and --exclude. Please use one or the other. Aborting."
171
- puts exit_message
150
+ args = meta_args[0]
151
+ @singular = args.first.tableize.singularize # should be in form hello_world
172
152
 
173
- raise(HotGlue::Error, exit_message)
174
- end
153
+ if @singular.include?("/")
154
+ @singular = @singular.split("/").last
155
+ end
175
156
 
157
+ @plural = options['plural'] || @singular.pluralize # respects what you set in inflections.rb, to override, use plural option
158
+ @namespace = options['namespace'] || nil
159
+ use_controller_name = plural.titleize.gsub(" ", "")
160
+ @controller_build_name = (( @namespace.titleize.gsub(" ","") + "::" if @namespace) || "") + use_controller_name + "Controller"
161
+ @controller_build_folder = use_controller_name.underscore
162
+ @controller_build_folder_singular = singular
176
163
 
177
- if @stimulus_syntax.nil?
178
- @stimulus_syntax = true
179
- end
164
+ @auth = options['auth'] || "current_user"
165
+ @auth_identifier = options['auth_identifier'] || (! @god && @auth.gsub("current_", "")) || nil
180
166
 
181
- if !options['markup'].nil?
182
- 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`"
183
- raise(HotGlue::Error, message)
184
- end
167
+ if options['nest']
168
+ raise HotGlue::Error, "STOP: the flag --nest has been replaced with --nested; please re-run using the --nested flag"
169
+ end
170
+ @nested = (!options['nested'].empty? && options['nested']) || nil
171
+ @singular_class = args.first # note this is the full class name with a model namespace
185
172
 
186
- yaml_from_config = YAML.load(File.read("config/hot_glue.yml"))
187
- @markup = yaml_from_config[:markup]
188
- @sample_file_path = yaml_from_config[:sample_file_path]
173
+ setup_attachments
189
174
 
190
- if options['layout']
191
- layout = options['layout']
192
- else
193
- layout = yaml_from_config[:layout]
175
+ @exclude_fields = []
176
+ @exclude_fields += options['exclude'].split(",").collect(&:to_sym)
194
177
 
195
- if !['hotglue', 'bootstrap', 'tailwind'].include? layout
196
- raise "Invalid option #{layout} in Hot glue config (config/hot_glue.yml). You must either use --layout= when generating or have a file config/hotglue.yml; specify layout as either 'hotglue' or 'bootstrap'"
197
- end
198
- end
178
+ if !options['include'].empty?
179
+ @include_fields = []
199
180
 
200
- @layout_strategy =
201
- case layout
202
- when 'bootstrap'
203
- LayoutStrategy::Bootstrap.new(self)
204
- when 'tailwind'
205
- LayoutStrategy::Tailwind.new(self)
206
- when 'hotglue'
207
- LayoutStrategy::HotGlue.new(self)
208
- end
181
+ # semicolon to denote layout columns; commas separate fields
182
+ @include_fields += options['include'].split(":").collect{|x|x.split(",")}.flatten.collect(&:to_sym)
183
+ end
209
184
 
210
- args = meta_args[0]
211
- @singular = args.first.tableize.singularize # should be in form hello_world
185
+ @show_only = []
186
+ if !options['show_only'].empty?
187
+ @show_only += options['show_only'].split(",").collect(&:to_sym)
188
+ end
212
189
 
213
- if @singular.include?("/")
214
- @singular = @singular.split("/").last
215
- end
190
+ @update_show_only = []
191
+ if !options['update_show_only'].empty?
192
+ @update_show_only += options['update_show_only'].split(",").collect(&:to_sym)
193
+ end
216
194
 
217
- @plural = options['plural'] || @singular.pluralize # respects what you set in inflections.rb, to override, use plural option
218
- @namespace = options['namespace'] || nil
219
- use_controller_name = plural.titleize.gsub(" ", "")
220
- @controller_build_name = (( @namespace.titleize.gsub(" ","") + "::" if @namespace) || "") + use_controller_name + "Controller"
221
- @controller_build_folder = use_controller_name.underscore
222
- @controller_build_folder_singular = singular
223
195
 
224
- @auth = options['auth'] || "current_user"
225
- @auth_identifier = options['auth_identifier'] || (! @god && @auth.gsub("current_", "")) || nil
196
+ # syntax should be xyz_id{xyz_email},abc_id{abc_email}
197
+ # instead of a drop-down for the foreign entity, a text field will be presented
198
+ # You must ALSO use a factory that contains a parameter of the same name as the 'value' (for example, `xyz_email`)
226
199
 
227
- if options['nest']
228
- raise HotGlue::Error, "STOP: the flag --nest has been replaced with --nested; please re-run using the --nested flag"
229
- end
230
- @nested = (!options['nested'].empty? && options['nested']) || nil
231
- @singular_class = args.first # note this is the full class name with a model namespace
200
+ alt_lookups_entry = options['alt_foreign_key_lookup'].split(",")
201
+ @alt_lookups = {}
202
+ @alt_foreign_key_lookup = alt_lookups_entry.each do |setting|
203
+ setting =~ /(.*){(.*)}/
204
+ key, lookup_as = $1, $2
205
+ assoc = eval("#{class_name}.reflect_on_association(:#{key.to_s.gsub("_id","")}).class_name")
232
206
 
233
- setup_attachments
207
+ data = {lookup_as: lookup_as.gsub("+",""),
208
+ assoc: assoc,
209
+ with_create: lookup_as.include?("+")}
210
+ @alt_lookups[key] = data
211
+ end
234
212
 
235
- @exclude_fields = []
236
- @exclude_fields += options['exclude'].split(",").collect(&:to_sym)
213
+ puts "------ ALT LOOKUPS for #{@alt_lookups}"
237
214
 
238
- if !options['include'].empty?
239
- @include_fields = []
215
+ @update_alt_lookups = @alt_lookups.collect{|key, value|
216
+ @update_show_only.include?(key) ?
217
+ { key: value }
218
+ : nil}.compact
240
219
 
241
- # semicolon to denote layout columns; commas separate fields
242
- @include_fields += options['include'].split(":").collect{|x|x.split(",")}.flatten.collect(&:to_sym)
243
- end
220
+ @label = options['label'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_singular)") ? eval("#{class_name}.class_variable_get(:@@table_label_singular)") : singular.gsub("_", " ").titleize )
221
+ @list_label_heading = options['list_label_heading'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_plural)") ? eval("#{class_name}.class_variable_get(:@@table_label_plural)") : plural.gsub("_", " ").upcase )
244
222
 
245
- @show_only = []
246
- if !options['show_only'].empty?
247
- @show_only += options['show_only'].split(",").collect(&:to_sym)
248
- end
223
+ @new_button_label = options['new_button_label'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_singular)") ? "New " + eval("#{class_name}.class_variable_get(:@@table_label_singular)") : "New " + singular.gsub("_", " ").titleize )
224
+ @new_form_heading = options['new_form_heading'] || "New #{@label}"
249
225
 
250
- @update_show_only = []
251
- if !options['update_show_only'].empty?
252
- @update_show_only += options['update_show_only'].split(",").collect(&:to_sym)
253
- end
254
226
 
255
227
 
256
- # syntax should be xyz_id{xyz_email},abc_id{abc_email}
257
- # instead of a drop-down for the foreign entity, a text field will be presented
258
- # You must ALSO use a factory that contains a parameter of the same name as the 'value' (for example, `xyz_email`)
228
+ setup_hawk_keys
229
+ @form_placeholder_labels = options['form_placeholder_labels'] # true or false
230
+ @inline_list_labels = options['inline_list_labels'] || 'omit' # 'before','after','omit'
259
231
 
260
- alt_lookups_entry = options['alt_foreign_key_lookup'].split(",")
261
- @alt_lookups = {}
262
- @alt_foreign_key_lookup = alt_lookups_entry.each do |setting|
263
- setting =~ /(.*){(.*)}/
264
- key, lookup_as = $1, $2
265
- assoc = eval("#{class_name}.reflect_on_association(:#{key.to_s.gsub("_id","")}).class_name")
266
232
 
267
- data = {lookup_as: lookup_as.gsub("+",""),
268
- assoc: assoc,
269
- with_create: lookup_as.include?("+")}
270
- @alt_lookups[key] = data
271
- end
233
+ @form_labels_position = options['form_labels_position']
234
+ if !['before','after','omit'].include?(@form_labels_position)
235
+ 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"
236
+ end
272
237
 
273
- puts "------ ALT LOOKUPS for #{@alt_lookups}"
238
+ if !['before','after','omit'].include?(@inline_list_labels)
239
+ 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)"
240
+ end
274
241
 
275
- @update_alt_lookups = @alt_lookups.collect{|key, value|
276
- @update_show_only.include?(key) ?
277
- { key: value }
278
- : nil}.compact
279
242
 
280
- @label = options['label'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_singular)") ? eval("#{class_name}.class_variable_get(:@@table_label_singular)") : singular.gsub("_", " ").titleize )
281
- @list_label_heading = options['list_label_heading'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_plural)") ? eval("#{class_name}.class_variable_get(:@@table_label_plural)") : plural.gsub("_", " ").upcase )
282
243
 
283
- @new_button_label = options['new_button_label'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_singular)") ? "New " + eval("#{class_name}.class_variable_get(:@@table_label_singular)") : "New " + singular.gsub("_", " ").titleize )
284
- @new_form_heading = options['new_form_heading'] || "New #{@label}"
285
244
 
286
245
 
287
246
 
288
- setup_hawk_keys
289
- @form_placeholder_labels = options['form_placeholder_labels'] # true or false
290
- @inline_list_labels = options['inline_list_labels'] || 'omit' # 'before','after','omit'
247
+ @god = options['god'] || options['gd'] || false
248
+ @specs_only = options['specs_only'] || false
291
249
 
250
+ @no_specs = options['no_specs'] || false
251
+ @no_delete = options['no_delete'] || false
292
252
 
293
- @form_labels_position = options['form_labels_position']
294
- if !['before','after','omit'].include?(@form_labels_position)
295
- 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"
296
- end
253
+ @no_create = options['no_create'] || false
254
+ @no_paginate = options['no_paginate'] || false
255
+ @big_edit = options['big_edit']
297
256
 
298
- if !['before','after','omit'].include?(@inline_list_labels)
299
- 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)"
300
- end
257
+ @no_edit = options['no_edit'] || false
258
+ @no_list = options['no_list'] || false
259
+ @no_list_label = options['no_list_label'] || false
260
+ @no_list_heading = options['no_list_heading'] || false
261
+ @stacked_downnesting = options['stacked_downnesting']
301
262
 
302
263
 
303
264
 
304
- if @markup == "erb"
305
- @template_builder = HotGlue::ErbTemplate.new(
306
- layout_strategy: @layout_strategy,
307
- magic_buttons: @magic_buttons,
308
- small_buttons: @small_buttons,
309
- inline_list_labels: @inline_list_labels,
310
- show_only: @show_only,
311
- update_show_only: @update_show_only,
312
- singular_class: singular_class,
313
- singular: singular,
314
- hawk_keys: @hawk_keys,
315
- ownership_field: @ownership_field,
316
- form_labels_position: @form_labels_position,
317
- form_placeholder_labels: @form_placeholder_labels,
318
- alt_lookups: @alt_lookups,
319
- attachments: @attachments,
320
- )
321
- elsif @markup == "slim"
322
- raise(HotGlue::Error, "SLIM IS NOT IMPLEMENTED")
323
- elsif @markup == "haml"
324
- raise(HotGlue::Error, "HAML IS NOT IMPLEMENTED")
325
- end
326
265
 
327
- @god = options['god'] || options['gd'] || false
328
- @specs_only = options['specs_only'] || false
266
+ @display_list_after_update = options['display_list_after_update'] || false
267
+ @smart_layout = options['smart_layout']
329
268
 
330
- @no_specs = options['no_specs'] || false
331
- @no_delete = options['no_delete'] || false
269
+ if options['include'].include?(":") && @smart_layout
270
+ 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"
271
+ end
332
272
 
333
- @no_create = options['no_create'] || false
334
- @no_paginate = options['no_paginate'] || false
335
- @big_edit = options['big_edit']
273
+ @container_name = @layout_strategy.container_name
274
+ @downnest = options['downnest'] || false
336
275
 
337
- @no_edit = options['no_edit'] || false
338
- @no_list = options['no_list'] || false
339
- @no_list_label = options['no_list_label'] || false
340
- @no_list_heading = options['no_list_heading'] || false
341
- @stacked_downnesting = options['stacked_downnesting']
276
+ @downnest_children = [] # TODO: defactor @downnest_children in favor of downnest_object
277
+ @downnest_object = {}
278
+ if @downnest
279
+ @downnest_children = @downnest.split(",").map{|child| child.gsub("+","")}
280
+ @downnest_object = HotGlue.construct_downnest_object(@downnest)
281
+ end
342
282
 
283
+ if @god
284
+ @auth = nil
285
+ end
343
286
 
287
+ # when in self auth, the object is the same as the authenticated object
344
288
 
289
+ if @auth && auth_identifier == @singular
290
+ @self_auth = true
291
+ end
345
292
 
346
- @display_list_after_update = options['display_list_after_update'] || false
347
- @smart_layout = options['smart_layout']
293
+ if @self_auth && !@no_create
294
+ 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"
295
+ end
348
296
 
349
- if options['include'].include?(":") && @smart_layout
350
- 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"
351
- end
297
+ @magic_buttons = []
298
+ if options['magic_buttons']
299
+ @magic_buttons = options['magic_buttons'].split(',')
300
+ end
352
301
 
353
- @container_name = @layout_strategy.container_name
354
- @downnest = options['downnest'] || false
355
302
 
356
- @downnest_children = [] # TODO: defactor @downnest_children in favor of downnest_object
357
- @downnest_object = {}
358
- if @downnest
359
- @downnest_children = @downnest.split(",").map{|child| child.gsub("+","")}
360
- @downnest_object = HotGlue.construct_downnest_object(@downnest)
361
- end
303
+ @small_buttons = options['small_buttons'] || false
362
304
 
363
- if @god
364
- @auth = nil
365
- end
305
+ @build_update_action = !@no_edit || !@magic_buttons.empty?
306
+ # if the magic buttons are present, build the update action anyway
366
307
 
367
- # when in self auth, the object is the same as the authenticated object
308
+ @ujs_syntax = options['ujs_syntax']
309
+ if !@ujs_syntax
310
+ @ujs_syntax = !defined?(Turbo::Engine)
311
+ end
368
312
 
369
- if @auth && auth_identifier == @singular
370
- @self_auth = true
371
- end
372
313
 
373
- if @self_auth && !@no_create
374
- 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"
375
- end
314
+ # NEST CHAIN
315
+ # new syntax
316
+ # @nested_set = [
317
+ # {
318
+ # singular: ...,
319
+ # plural: ...,
320
+ # optional: false
321
+ # }]
322
+ @nested_set = []
376
323
 
377
- @magic_buttons = []
378
- if options['magic_buttons']
379
- @magic_buttons = options['magic_buttons'].split(',')
380
- end
324
+ if ! @nested.nil?
325
+ @nested_set = @nested.split("/").collect { |arg|
326
+ is_optional = arg.start_with?("~")
327
+ arg.gsub!("~","")
328
+ {
329
+ singular: arg,
330
+ plural: arg.pluralize,
331
+ optional: is_optional
332
+ }
333
+ }
334
+ puts "NESTING: #{@nested_set}"
335
+ end
381
336
 
337
+ # OBJECT OWNERSHIP & NESTING
338
+ @reference_name = HotGlue.derrive_reference_name(singular_class)
339
+ if @auth && @self_auth
340
+ @object_owner_sym = @auth.gsub("current_", "").to_sym
341
+ @object_owner_eval = @auth
342
+ @object_owner_optional = false
343
+ @object_owner_name = @auth.gsub("current_", "").to_s
382
344
 
383
- @small_buttons = options['small_buttons'] || false
384
345
 
385
- @build_update_action = !@no_edit || !@magic_buttons.empty?
386
- # if the magic buttons are present, build the update action anyway
346
+ elsif @auth && ! @self_auth && @nested_set.none? && !@auth.include?(".")
347
+ @object_owner_sym = @auth.gsub("current_", "").to_sym
348
+ @object_owner_eval = @auth
349
+ @object_owner_optional = false
350
+ @object_owner_name = @auth.gsub("current_", "").to_s
387
351
 
388
- @ujs_syntax = options['ujs_syntax']
389
- if !@ujs_syntax
390
- @ujs_syntax = !defined?(Turbo::Engine)
352
+ elsif @auth && @auth.include?(".")
353
+ @object_owner_sym = nil
354
+ @object_owner_eval = @auth
355
+ else
356
+ if @nested_set.any?
357
+ @object_owner_sym = @nested_set.last[:singular].to_sym
358
+ @object_owner_eval = "@#{@nested_set.last[:singular]}"
359
+ @object_owner_name = @nested_set.last[:singular]
360
+ @object_owner_optional = @nested_set.last[:optional]
361
+ else
362
+ @object_owner_sym = nil
363
+ @object_owner_eval = ""
391
364
  end
365
+ end
392
366
 
393
367
 
394
- # NEST CHAIN
395
- # new syntax
396
- # @nested_set = [
397
- # {
398
- # singular: ...,
399
- # plural: ...,
400
- # optional: false
401
- # }]
402
- @nested_set = []
403
-
404
- if ! @nested.nil?
405
- @nested_set = @nested.split("/").collect { |arg|
406
- is_optional = arg.start_with?("~")
407
- arg.gsub!("~","")
408
- {
409
- singular: arg,
410
- plural: arg.pluralize,
411
- optional: is_optional
412
- }
413
- }
414
- puts "NESTING: #{@nested_set}"
415
- end
416
-
417
- # OBJECT OWNERSHIP & NESTING
418
- @reference_name = HotGlue.derrive_reference_name(singular_class)
419
- if @auth && @self_auth
420
- @object_owner_sym = @auth.gsub("current_", "").to_sym
421
- @object_owner_eval = @auth
422
- @object_owner_optional = false
423
- @object_owner_name = @auth.gsub("current_", "").to_s
368
+ @factory_creation = options['factory_creation'].gsub(";", "\n")
369
+ identify_object_owner
370
+ setup_fields
424
371
 
372
+ if (@columns - @show_only - (@ownership_field ? [@ownership_field.to_sym] : [])).empty?
373
+ @no_field_form = true
374
+ end
425
375
 
426
- elsif @auth && ! @self_auth && @nested_set.none? && !@auth.include?(".")
427
- @object_owner_sym = @auth.gsub("current_", "").to_sym
428
- @object_owner_eval = @auth
429
- @object_owner_optional = false
430
- @object_owner_name = @auth.gsub("current_", "").to_s
376
+ buttons_width = ((!@no_edit && 1) || 0) + ((!@no_delete && 1) || 0) + @magic_buttons.count
431
377
 
432
- elsif @auth && @auth.include?(".")
433
- @object_owner_sym = nil
434
- @object_owner_eval = @auth
435
- else
436
- if @nested_set.any?
437
- @object_owner_sym = @nested_set.last[:singular].to_sym
438
- @object_owner_eval = "@#{@nested_set.last[:singular]}"
439
- @object_owner_name = @nested_set.last[:singular]
440
- @object_owner_optional = @nested_set.last[:optional]
441
- else
442
- @object_owner_sym = nil
443
- @object_owner_eval = ""
444
- end
378
+ # build a new polymorphic object
379
+ @associations = []
380
+ @columns_map = {}
381
+ @columns.each do |col|
382
+ if !(@the_object.columns_hash.keys.include?(col.to_s) || @attachments.keys.include?(col))
383
+ raise "couldn't find #{col} in either field list or attachments list"
445
384
  end
446
385
 
447
-
448
- @factory_creation = options['factory_creation'].gsub(";", "\n")
449
- identify_object_owner
450
- setup_fields
451
-
452
- if (@columns - @show_only - (@ownership_field ? [@ownership_field.to_sym] : [])).empty?
453
- @no_field_form = true
386
+ if col.to_s.starts_with?("_")
387
+ @show_only << col
454
388
  end
455
389
 
456
- buttons_width = ((!@no_edit && 1) || 0) + ((!@no_delete && 1) || 0) + @magic_buttons.count
457
-
458
- builder = HotGlue::Layout::Builder.new(include_setting: options['include'],
459
- downnest_object: @downnest_object,
460
- buttons_width: buttons_width,
461
- columns: @columns,
462
- smart_layout: @smart_layout,
463
- stacked_downnesting: @stacked_downnesting)
464
- @layout_object = builder.construct
465
-
390
+ if @the_object.columns_hash.keys.include?(col.to_s)
391
+ type = @the_object.columns_hash[col.to_s].type
392
+ elsif @attachments.keys.include?(col)
393
+ type = :attachment
394
+ end
395
+ this_column_object = FieldFactory.new(name: col.to_s,
396
+ generator: self,
397
+ type: type)
398
+ field = this_column_object.field
399
+ if field.is_a?(AssociationField)
400
+ @associations << field.assoc_name.to_sym
401
+ end
402
+ @columns_map[col] = this_column_object.field
403
+ end
466
404
 
467
405
 
468
- @menu_file_exists = true if @nested_set.none? && File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
469
406
 
470
- @turbo_streams = !!options['with_turbo_streams']
407
+ # create the template object
408
+ if @markup == "erb"
409
+ @template_builder = HotGlue::ErbTemplate.new(
410
+ layout_strategy: @layout_strategy,
411
+ magic_buttons: @magic_buttons,
412
+ small_buttons: @small_buttons,
413
+ inline_list_labels: @inline_list_labels,
414
+ show_only: @show_only,
415
+ update_show_only: @update_show_only,
416
+ singular_class: singular_class,
417
+ singular: singular,
418
+ hawk_keys: @hawk_keys,
419
+ ownership_field: @ownership_field,
420
+ form_labels_position: @form_labels_position,
421
+ form_placeholder_labels: @form_placeholder_labels,
422
+ alt_lookups: @alt_lookups,
423
+ attachments: @attachments,
424
+ columns_map: @columns_map
425
+ )
426
+ elsif @markup == "slim"
427
+ raise(HotGlue::Error, "SLIM IS NOT IMPLEMENTED")
428
+ elsif @markup == "haml"
429
+ raise(HotGlue::Error, "HAML IS NOT IMPLEMENTED")
471
430
  end
472
431
 
432
+ builder = HotGlue::Layout::Builder.new(generator: self,
433
+ include_setting: options['include'],
434
+ buttons_width: buttons_width )
435
+ @layout_object = builder.construct
473
436
 
474
437
 
475
- def setup_hawk_keys
476
- @hawk_keys = {}
477
-
478
- if options["hawk"]
479
- options['hawk'].split(",").each do |hawk_entry|
480
- # format is: abc_id[thing]
481
438
 
482
- if hawk_entry.include?("{")
483
- hawk_entry =~ /(.*){(.*)}/
484
- key, hawk_to = $1, $2
485
- else
486
- key = hawk_entry
487
- hawk_to = @auth
488
- end
439
+ @menu_file_exists = true if @nested_set.none? && File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
489
440
 
490
- hawk_scope = key.gsub("_id", "").pluralize
491
- optional = eval(singular_class + ".reflect_on_association(:#{key.gsub('_id','')})").options[:optional]
441
+ @turbo_streams = !!options['with_turbo_streams']
442
+ end
492
443
 
493
- @hawk_keys[key.to_sym] = {bind_to: [hawk_to], optional: optional}
494
- use_shorthand = !options["hawk"].include?("{")
495
444
 
496
- if use_shorthand # only include the hawk scope if using the shorthand
497
- @hawk_keys[key.to_sym][:bind_to] << hawk_scope
498
- end
499
445
 
500
- end
446
+ def setup_hawk_keys
447
+ @hawk_keys = {}
501
448
 
502
- puts "HAWKING: #{@hawk_keys}"
503
- end
504
- end
449
+ if options["hawk"]
450
+ options['hawk'].split(",").each do |hawk_entry|
451
+ # format is: abc_id[thing]
505
452
 
453
+ if hawk_entry.include?("{")
454
+ hawk_entry =~ /(.*){(.*)}/
455
+ key, hawk_to = $1, $2
456
+ else
457
+ key = hawk_entry
458
+ hawk_to = @auth
459
+ end
506
460
 
507
- def setup_attachments
508
- @attachments = {}
461
+ hawk_scope = key.gsub("_id", "").pluralize
462
+ optional = eval(singular_class + ".reflect_on_association(:#{key.gsub('_id','')})").options[:optional]
509
463
 
510
- if options["attachments"]
464
+ @hawk_keys[key.to_sym] = {bind_to: [hawk_to], optional: optional}
465
+ use_shorthand = !options["hawk"].include?("{")
511
466
 
512
- options['attachments'].split(",").each do |attachment_entry|
513
- # format is: avatar{thumbnail|field_for_original_filename}
467
+ if use_shorthand # only include the hawk scope if using the shorthand
468
+ @hawk_keys[key.to_sym][:bind_to] << hawk_scope
469
+ end
514
470
 
515
- if attachment_entry.include?("{")
516
- num_params = attachment_entry.split("|").count
517
- if num_params == 1
518
- attachment_entry =~ /(.*){(.*)}/
519
- key, thumbnail = $1, $2
520
- elsif num_params == 2
521
- attachment_entry =~ /(.*){(.*)\|(.*)}/
522
- key, thumbnail, field_for_original_filename = $1, $2, $3
523
- elsif num_params > 2
524
- if num_params == 3
525
- attachment_entry =~ /(.*){(.*)\|(.*)\|(.*)}/
526
- key, thumbnail, field_for_original_filename, direct_upload = $1, $2, $3, $4
527
- elsif num_params > 3
528
- attachment_entry =~ /(.*){(.*)\|(.*)\|(.*)\|(.*)}/
529
- key, thumbnail, field_for_original_filename, direct_upload, dropzone = $1, $2, $3, $4, $5
530
- end
471
+ end
531
472
 
532
- field_for_original_filename = nil if field_for_original_filename == ""
473
+ puts "HAWKING: #{@hawk_keys}"
474
+ end
475
+ end
533
476
 
534
- if thumbnail == ''
535
- thumbnail = nil
536
- end
537
477
 
538
- if !direct_upload.nil? && direct_upload != "direct"
539
- raise HotGlue::Error, "received 3rd parameter in attachment long form specification that was not 'direct'; for direct uploads, just use 'direct' or leave off to disable"
540
- end
478
+ def setup_attachments
479
+ @attachments = {}
480
+
481
+ if options["attachments"]
482
+
483
+ options['attachments'].split(",").each do |attachment_entry|
484
+ # format is: avatar{thumbnail|field_for_original_filename}
485
+
486
+ if attachment_entry.include?("{")
487
+ num_params = attachment_entry.split("|").count
488
+ if num_params == 1
489
+ attachment_entry =~ /(.*){(.*)}/
490
+ key, thumbnail = $1, $2
491
+ elsif num_params == 2
492
+ attachment_entry =~ /(.*){(.*)\|(.*)}/
493
+ key, thumbnail, field_for_original_filename = $1, $2, $3
494
+ elsif num_params > 2
495
+ if num_params == 3
496
+ attachment_entry =~ /(.*){(.*)\|(.*)\|(.*)}/
497
+ key, thumbnail, field_for_original_filename, direct_upload = $1, $2, $3, $4
498
+ elsif num_params > 3
499
+ attachment_entry =~ /(.*){(.*)\|(.*)\|(.*)\|(.*)}/
500
+ key, thumbnail, field_for_original_filename, direct_upload, dropzone = $1, $2, $3, $4, $5
501
+ end
541
502
 
542
- if !dropzone.nil? && dropzone != "dropzone"
543
- raise HotGlue::Error, "received 4th parameter in attachme long form specification that was not 'dropzone'; for dropzone, just use 'dropzone' or leave off to disable"
544
- end
503
+ field_for_original_filename = nil if field_for_original_filename == ""
545
504
 
546
- if dropzone && !direct_upload
547
- raise HotGlue::Error, "dropzone requires direct_upload"
548
- end
505
+ if thumbnail == ''
506
+ thumbnail = nil
507
+ end
549
508
 
550
- if field_for_original_filename && direct_upload
551
- raise HotGlue::Error, "Unfortunately orig filename extraction doesn't work with direct upload; please set 2nd parameter to empty string to disable"
552
- end
509
+ if !direct_upload.nil? && direct_upload != "direct"
510
+ raise HotGlue::Error, "received 3rd parameter in attachment long form specification that was not 'direct'; for direct uploads, just use 'direct' or leave off to disable"
511
+ end
553
512
 
554
- direct_upload = !!direct_upload
555
- dropzone = !!dropzone
513
+ if !dropzone.nil? && dropzone != "dropzone"
514
+ raise HotGlue::Error, "received 4th parameter in attachme long form specification that was not 'dropzone'; for dropzone, just use 'dropzone' or leave off to disable"
556
515
  end
557
- else
558
- key = attachment_entry
559
516
 
560
- if !(eval("#{singular_class}.reflect_on_attachment(:#{attachment_entry})"))
561
- raise HotGlue::Error, "Could not find #{attachment_entry} attachment on #{singular_class}"
517
+ if dropzone && !direct_upload
518
+ raise HotGlue::Error, "dropzone requires direct_upload"
562
519
  end
563
- if eval("#{singular_class}.reflect_on_attachment(:#{attachment_entry}).variants.include?(:thumb)")
564
- thumbnail = "thumb"
565
- else
566
- thumbnail = nil
520
+
521
+ if field_for_original_filename && direct_upload
522
+ raise HotGlue::Error, "Unfortunately orig filename extraction doesn't work with direct upload; please set 2nd parameter to empty string to disable"
567
523
  end
568
524
 
569
- direct_upload = nil
570
- field_for_original_filename = nil
571
- dropzone = nil
525
+ direct_upload = !!direct_upload
526
+ dropzone = !!dropzone
527
+ end
528
+ else
529
+ key = attachment_entry
530
+
531
+ if !(eval("#{singular_class}.reflect_on_attachment(:#{attachment_entry})"))
532
+ raise HotGlue::Error, "Could not find #{attachment_entry} attachment on #{singular_class}"
533
+ end
534
+ if eval("#{singular_class}.reflect_on_attachment(:#{attachment_entry}).variants.include?(:thumb)")
535
+ thumbnail = "thumb"
536
+ else
537
+ thumbnail = nil
572
538
  end
573
539
 
574
- if thumbnail && !eval("#{singular_class}.reflect_on_attachment(:#{key}).variants.include?(:#{thumbnail})")
575
- raise HotGlue::Error, "you specified to use #{thumbnail} as the thumbnail but could not find any such variant on the #{key} attachment; add to your #{singular}.rb file:
540
+ direct_upload = nil
541
+ field_for_original_filename = nil
542
+ dropzone = nil
543
+ end
544
+
545
+ if thumbnail && !eval("#{singular_class}.reflect_on_attachment(:#{key}).variants.include?(:#{thumbnail})")
546
+ raise HotGlue::Error, "you specified to use #{thumbnail} as the thumbnail but could not find any such variant on the #{key} attachment; add to your #{singular}.rb file:
576
547
  has_one_attached :#{key} do |attachable|
577
548
  attachable.variant :#{thumbnail}, resize_to_limit: [100, 100]
578
549
  end
579
550
  "
580
- end
581
-
582
-
583
- @attachments[key.to_sym] = {thumbnail: thumbnail,
584
- field_for_original_filename: field_for_original_filename,
585
- direct_upload: direct_upload,
586
- dropzone: dropzone}
587
551
  end
588
552
 
589
- puts "ATTACHMENTS: #{@attachments}"
553
+
554
+ @attachments[key.to_sym] = {thumbnail: thumbnail,
555
+ field_for_original_filename: field_for_original_filename,
556
+ direct_upload: direct_upload,
557
+ dropzone: dropzone}
590
558
  end
559
+
560
+ puts "ATTACHMENTS: #{@attachments}"
591
561
  end
562
+ end
592
563
 
593
- def identify_object_owner
594
- auth_assoc = @auth && @auth.gsub("current_","")
564
+ def identify_object_owner
565
+ auth_assoc = @auth && @auth.gsub("current_","")
595
566
 
596
- if @object_owner_sym && ! @self_auth
597
- auth_assoc_field = auth_assoc + "_id" unless @god
598
- assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
567
+ if @object_owner_sym && ! @self_auth
568
+ auth_assoc_field = auth_assoc + "_id" unless @god
569
+ assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
599
570
 
600
- if assoc
601
- @ownership_field = assoc.name.to_s + "_id"
602
- elsif ! @nested_set.any?
603
- 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."
604
- raise(HotGlue::Error, exit_message)
571
+ if assoc
572
+ @ownership_field = assoc.name.to_s + "_id"
573
+ elsif ! @nested_set.any?
574
+ 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."
575
+ raise(HotGlue::Error, exit_message)
605
576
 
606
- else
607
- 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?
608
- 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?"
577
+ else
578
+ 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?
579
+ 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?"
609
580
  # else # NOTE: not reachable
610
581
  # 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."
611
- end
612
-
613
- raise(HotGlue::Error, exit_message)
614
582
  end
615
- elsif @object_owner_sym && ! @object_owner_eval.include?(".")
616
- @ownership_field = @object_owner_name + "_id"
583
+
584
+ raise(HotGlue::Error, exit_message)
617
585
  end
586
+ elsif @object_owner_sym && ! @object_owner_eval.include?(".")
587
+ @ownership_field = @object_owner_name + "_id"
618
588
  end
589
+ end
619
590
 
620
- def setup_fields
621
- if !@include_fields
622
- @exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
623
- :reset_password_token,
624
- :reset_password_sent_at, :remember_created_at,
625
- :confirmation_token, :confirmed_at,
626
- :confirmation_sent_at, :unconfirmed_email
627
-
628
- @exclude_fields.push( @ownership_field.to_sym ) if ! @ownership_field.nil?
591
+ def setup_fields
592
+ if !@include_fields
593
+ @exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
594
+ :reset_password_token,
595
+ :reset_password_sent_at, :remember_created_at,
596
+ :confirmation_token, :confirmed_at,
597
+ :confirmation_sent_at, :unconfirmed_email
629
598
 
599
+ @exclude_fields.push( @ownership_field.to_sym ) if ! @ownership_field.nil?
630
600
 
631
- @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
632
601
 
602
+ @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
633
603
 
634
- else
635
- @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| !@include_fields.include?(field) }
636
- end
637
604
 
638
- if @attachments.any?
639
- puts "adding attachments-as-columns: #{@attachments}"
640
- @attachments.keys.each do |attachment|
641
- @columns << attachment if !@columns.include?(attachment)
642
- end
605
+ else
606
+ @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| !@include_fields.include?(field) }
607
+ end
643
608
 
644
- check_if_sample_file_is_present
609
+ if @attachments.any?
610
+ puts "adding attachments-as-columns: #{@attachments}"
611
+ @attachments.keys.each do |attachment|
612
+ @columns << attachment if !@columns.include?(attachment)
645
613
  end
646
614
 
647
-
648
- # build a new polymorphic object
649
- @associations = []
650
- @columns_map = {}
651
- @columns.each do |col|
652
- if !(@the_object.columns_hash.keys.include?(col.to_s) || @attachments.keys.include?(col))
653
- raise "couldn't find #{col} in either field list or attachments list"
654
- end
655
-
656
- if col.to_s.starts_with?("_")
657
- @show_only << col
658
- end
659
-
660
- if @the_object.columns_hash.keys.include?(col.to_s)
661
- type = @the_object.columns_hash[col.to_s].type
662
- elsif @attachments.keys.include?(col)
663
- type = :attachment
664
- end
665
- this_column_object = FieldFactory.new(name: col.to_s,
666
- generator: self,
667
- type: type)
668
- field = this_column_object.field
669
- if field.is_a?(AssociationField)
670
- @associations << field.assoc_name.to_sym
671
- end
672
- @columns_map[col] = this_column_object.field
615
+ check_if_sample_file_is_present
616
+ end
617
+ end
673
618
 
674
619
 
675
620
 
676
- end
677
- end
678
621
 
679
622
 
680
- def check_if_sample_file_is_present
681
- if sample_file_path.nil?
682
- puts "you have no sample file path set in config/hot_glue.yml"
683
- settings = File.read("config/hot_glue.yml")
684
- @sample_file_path = "spec/files/computer_code.jpg"
685
- added_setting = ":sample_file_path: #{sample_file_path}"
686
- File.open("config/hot_glue.yml", "w") { |f| f.write settings + "\n" + added_setting }
687
623
 
688
- puts "adding `#{added_setting}` to config/hot_glue.yml"
689
- elsif ! File.exist?(sample_file_path)
690
- puts "NO SAMPLE FILE FOUND: adding sample file at #{sample_file_path}"
691
- template "computer_code.jpg", File.join("#{filepath_prefix}spec/files/", "computer_code.jpg")
692
- end
624
+ def check_if_sample_file_is_present
625
+ if sample_file_path.nil?
626
+ puts "you have no sample file path set in config/hot_glue.yml"
627
+ settings = File.read("config/hot_glue.yml")
628
+ @sample_file_path = "spec/files/computer_code.jpg"
629
+ added_setting = ":sample_file_path: #{sample_file_path}"
630
+ File.open("config/hot_glue.yml", "w") { |f| f.write settings + "\n" + added_setting }
693
631
 
694
- puts ""
632
+ puts "adding `#{added_setting}` to config/hot_glue.yml"
633
+ elsif ! File.exist?(sample_file_path)
634
+ puts "NO SAMPLE FILE FOUND: adding sample file at #{sample_file_path}"
635
+ template "computer_code.jpg", File.join("#{filepath_prefix}spec/files/", "computer_code.jpg")
695
636
  end
696
637
 
697
- def fields_filtered_for_email_lookups
698
- @columns.reject{|c| @alt_lookups.keys.include?(c) } + @alt_lookups.values.map{|v| ("__lookup_#{v[:lookup_as]}").to_sym}
699
- end
638
+ puts ""
639
+ end
700
640
 
701
- def creation_syntax
702
- merge_with = @alt_lookups.collect{ |key, data|
703
- "#{data[:assoc].downcase}: #{data[:assoc].downcase}_factory.#{data[:assoc].downcase}"
704
- }.join(", ")
641
+ def fields_filtered_for_email_lookups
642
+ @columns.reject{|c| @alt_lookups.keys.include?(c) } + @alt_lookups.values.map{|v| ("__lookup_#{v[:lookup_as]}").to_sym}
643
+ end
705
644
 
706
- if @factory_creation == ''
707
- "@#{singular } = #{ class_name }.create(modified_params)"
708
- else
709
- "#{@factory_creation}\n" +
710
- " @#{singular } = #{ class_name }.create(modified_params#{'.merge(' + merge_with + ')' if !merge_with.empty?})"
711
- end
712
- end
645
+ def creation_syntax
646
+ merge_with = @alt_lookups.collect{ |key, data|
647
+ "#{data[:assoc].downcase}: #{data[:assoc].downcase}_factory.#{data[:assoc].downcase}"
648
+ }.join(", ")
713
649
 
714
- def auth_root
715
- "authenticate_" + @auth_identifier.split(".")[0] + "!"
650
+ if @factory_creation == ''
651
+ "@#{singular } = #{ class_name }.create(modified_params#{'.merge(' + merge_with + ')' if !merge_with.empty?})"
652
+ else
653
+ "#{@factory_creation}\n" +
654
+ " @#{singular } = factory.#{singular}"
716
655
  end
656
+ end
717
657
 
718
- def formats
719
- [format]
720
- end
658
+ def auth_root
659
+ "authenticate_" + @auth_identifier.split(".")[0] + "!"
660
+ end
721
661
 
722
- def format
723
- nil
724
- end
662
+ def formats
663
+ [format]
664
+ end
725
665
 
726
- def filepath_prefix
727
- 'spec/dummy/' if Rails.env.test?
728
- end
666
+ def format
667
+ nil
668
+ end
729
669
 
730
- def copy_controller_and_spec_files
731
- @default_colspan = @columns.size
732
- unless @specs_only
733
- template "controller.rb.erb", File.join("#{filepath_prefix}app/controllers#{namespace_with_dash}", "#{@controller_build_folder}_controller.rb")
734
- if @namespace
735
- begin
736
- eval(controller_descends_from)
737
- rescue NameError => e
738
- template "base_controller.rb.erb", File.join("#{filepath_prefix}app/controllers#{namespace_with_dash}", "base_controller.rb")
739
- end
670
+ def filepath_prefix
671
+ 'spec/dummy/' if Rails.env.test?
672
+ end
673
+
674
+ def copy_controller_and_spec_files
675
+ @default_colspan = @columns.size
676
+ unless @specs_only
677
+ template "controller.rb.erb", File.join("#{filepath_prefix}app/controllers#{namespace_with_dash}", "#{@controller_build_folder}_controller.rb")
678
+ if @namespace
679
+ begin
680
+ eval(controller_descends_from)
681
+ rescue NameError => e
682
+ template "base_controller.rb.erb", File.join("#{filepath_prefix}app/controllers#{namespace_with_dash}", "base_controller.rb")
740
683
  end
741
684
  end
685
+ end
742
686
 
743
- unless @no_specs
744
- dest_file = File.join("#{filepath_prefix}spec/features#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
745
-
746
- if File.exist?(dest_file)
747
- existing_file = File.open(dest_file)
748
- existing_content = existing_file.read
749
- if existing_content =~ /\#HOTGLUE-SAVESTART/
750
- if existing_content !~ /\#HOTGLUE-END/
751
- raise "Your file at #{dest_file} contains a #HOTGLUE-SAVESTART marker without #HOTGLUE-END"
752
- end
753
- @existing_content = existing_content[(existing_content =~ /\#HOTGLUE-SAVESTART/) .. (existing_content =~ /\#HOTGLUE-END/)-1]
754
- @existing_content << "#HOTGLUE-END"
687
+ unless @no_specs
688
+ dest_file = File.join("#{filepath_prefix}spec/features#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
755
689
 
690
+ if File.exist?(dest_file)
691
+ existing_file = File.open(dest_file)
692
+ existing_content = existing_file.read
693
+ if existing_content =~ /\#HOTGLUE-SAVESTART/
694
+ if existing_content !~ /\#HOTGLUE-END/
695
+ raise "Your file at #{dest_file} contains a #HOTGLUE-SAVESTART marker without #HOTGLUE-END"
756
696
  end
757
- existing_file.rewind
758
- else
759
- @existing_content = " #HOTGLUE-SAVESTART\n #HOTGLUE-END"
760
- end
697
+ @existing_content = existing_content[(existing_content =~ /\#HOTGLUE-SAVESTART/) .. (existing_content =~ /\#HOTGLUE-END/)-1]
698
+ @existing_content << "#HOTGLUE-END"
761
699
 
762
-
763
- template "system_spec.rb.erb", dest_file
700
+ end
701
+ existing_file.rewind
702
+ else
703
+ @existing_content = " #HOTGLUE-SAVESTART\n #HOTGLUE-END"
764
704
  end
765
705
 
766
- template "#{@markup}/_errors.#{@markup}", File.join("#{filepath_prefix}app/views#{namespace_with_dash}", "_errors.#{@markup}")
767
- end
768
706
 
769
- def spec_foreign_association_merge_hash
770
- ", #{testing_name}: #{testing_name}1"
707
+ template "system_spec.rb.erb", dest_file
771
708
  end
772
709
 
773
- def testing_name
774
- singular_class.gsub("::","_").underscore
775
- end
776
-
777
- def spec_related_column_lets
778
- @columns_map.collect { |col, col_object|
779
- col_object.spec_related_column_lets
780
- }.join("\n")
710
+ if File.exist?("#{filepath_prefix}app/views#{namespace_with_dash}/_errors.#{@markup}")
711
+ File.delete("#{filepath_prefix}app/views#{namespace_with_dash}/_errors.#{@markup}")
781
712
  end
713
+ end
782
714
 
783
- def list_column_headings
784
- @template_builder.list_column_headings(
785
- layout_object: @layout_object,
786
- col_identifier: @layout_strategy.column_classes_for_column_headings,
787
- column_width: @layout_strategy.column_width,
788
- singular: @singular
789
- )
790
- end
715
+ def spec_foreign_association_merge_hash
716
+ ", #{testing_name}: #{testing_name}1"
717
+ end
791
718
 
792
- def columns_spec_with_sample_data
793
- @columns_map.map { |col, col_object|
794
- unless col_object.is_a?(AssociationField)
795
- random_data = col_object.spec_random_data
796
- col.to_s + ": '" + random_data.to_s + "'"
797
- end
798
- }.join(", ")
799
- end
719
+ def testing_name
720
+ singular_class.gsub("::","_").underscore
721
+ end
800
722
 
801
- def regenerate_me_code
802
- "rails generate hot_glue:scaffold #{ @meta_args[0][0] } #{@meta_args[1].collect{|x| x.gsub(/\s*=\s*([\S\s]+)/, '=\'\1\'')}.join(" ")}"
803
- end
723
+ def spec_related_column_lets
724
+ @columns_map.collect { |col, col_object|
725
+ col_object.spec_related_column_lets
726
+ }.join("\n")
727
+ end
804
728
 
805
- def object_parent_mapping_as_argument_for_specs
729
+ def list_column_headings
730
+ @template_builder.list_column_headings(
731
+ layout_object: @layout_object,
732
+ col_identifier: @layout_strategy.column_classes_for_column_headings,
733
+ column_width: @layout_strategy.column_width,
734
+ singular: @singular
735
+ )
736
+ end
806
737
 
807
- if @self_auth
808
- ""
809
- elsif @nested_set.any? && ! @nested_set.last[:optional]
810
- ", " + @nested_set.last[:singular] + ": " + @nested_set.last[:singular]
811
- elsif @auth && !@god
812
- ", #{@auth_identifier}: #{@auth}"
738
+ def columns_spec_with_sample_data
739
+ @columns_map.map { |col, col_object|
740
+ unless col_object.is_a?(AssociationField)
741
+ random_data = col_object.spec_random_data
742
+ col.to_s + ": '" + random_data.to_s + "'"
813
743
  end
814
- end
744
+ }.join(", ")
745
+ end
815
746
 
816
- def objest_nest_factory_setup
817
- res = ""
818
- if @auth
819
- last_parent = ", #{@auth_identifier}: #{@auth}"
820
- end
747
+ def regenerate_me_code
748
+ "rails generate hot_glue:scaffold #{ @meta_args[0][0] } #{@meta_args[1].collect{|x| x.gsub(/\s*=\s*([\S\s]+)/, '=\'\1\'')}.join(" ")}"
749
+ end
821
750
 
822
- @nested_set.each do |arg|
823
- res << " let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
824
- last_parent = ", #{arg[:singular]}: #{arg[:singular]}"
825
- end
826
- res
827
- end
751
+ def object_parent_mapping_as_argument_for_specs
828
752
 
829
- def objest_nest_params_by_id_for_specs
830
- @nested_set.map{|arg|
831
- "#{arg[:singular]}_id: #{arg[:singular]}.id"
832
- }.join(",\n ")
753
+ if @self_auth
754
+ ""
755
+ elsif @nested_set.any? && ! @nested_set.last[:optional]
756
+ ", " + @nested_set.last[:singular] + ": " + @nested_set.last[:singular]
757
+ elsif @auth && !@god
758
+ ", #{@auth_identifier}: #{@auth}"
833
759
  end
760
+ end
834
761
 
835
- def controller_class_name
836
- @controller_build_name
762
+ def objest_nest_factory_setup
763
+ res = ""
764
+ if @auth
765
+ last_parent = ", #{@auth_identifier}: #{@auth}"
837
766
  end
838
767
 
839
- def plural_name
840
- plural
768
+ @nested_set.each do |arg|
769
+ res << " let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
770
+ last_parent = ", #{arg[:singular]}: #{arg[:singular]}"
841
771
  end
772
+ res
773
+ end
842
774
 
843
- def auth_identifier
844
- @auth_identifier
845
- end
775
+ def objest_nest_params_by_id_for_specs
776
+ @nested_set.map{|arg|
777
+ "#{arg[:singular]}_id: #{arg[:singular]}.id"
778
+ }.join(",\n ")
779
+ end
846
780
 
847
- def capybara_make_updates(which_partial = :create)
848
- @columns_map.map { | col, col_obj|
849
- show_only_list = which_partial == :create ? @show_only : (@update_show_only+@show_only)
781
+ def controller_class_name
782
+ @controller_build_name
783
+ end
850
784
 
851
- if show_only_list.include?(col)
852
- " page.should have_no_selector(:css, \"[name='#{testing_name}[#{ col.to_s }]'\")"
853
- else
854
- col_obj.spec_setup_and_change_act(which_partial)
855
- end
856
- }.join("\n")
857
- end
785
+ def plural_name
786
+ plural
787
+ end
858
788
 
859
- def path_helper_args
860
- if @nested_set.any? && @nested
861
- [(@nested_set).collect{|a| "#{a[:singular]}"} , singular].join(",")
862
- else
863
- singular
864
- end
865
- end
789
+ def auth_identifier
790
+ @auth_identifier
791
+ end
792
+
793
+ def capybara_make_updates(which_partial = :create)
794
+ @columns_map.map { | col, col_obj|
795
+ show_only_list = which_partial == :create ? @show_only : (@update_show_only+@show_only)
866
796
 
867
- def path_helper_singular
868
- if @nested
869
- "#{@namespace+"_" if @namespace}#{(@nested_set.collect{|x| x[:singular]}.join("_") + "_" if @nested_set.any?)}#{@controller_build_folder_singular}_path"
797
+ if show_only_list.include?(col)
798
+ " page.should have_no_selector(:css, \"[name='#{testing_name}[#{ col.to_s }]'\")"
870
799
  else
871
- "#{@namespace+"_" if @namespace}#{@controller_build_folder_singular}_path"
800
+ col_obj.spec_setup_and_change_act(which_partial)
872
801
  end
873
- end
802
+ }.join("\n")
803
+ end
874
804
 
875
- def path_helper_plural
876
- HotGlue.optionalized_ternary(namespace: @namespace,
877
- target: @controller_build_folder,
878
- nested_set: @nested_set)
805
+ def path_helper_args
806
+ if @nested_set.any? && @nested
807
+ [(@nested_set).collect{|a| "#{a[:singular]}"} , singular].join(",")
808
+ else
809
+ singular
879
810
  end
811
+ end
880
812
 
881
- def form_path_new_helper
882
- HotGlue.optionalized_ternary(namespace: @namespace,
883
- target: @controller_build_folder,
884
- nested_set: @nested_set,
885
- with_params: true,
886
- top_level: false)
813
+ def path_helper_singular
814
+ if @nested
815
+ "#{@namespace+"_" if @namespace}#{(@nested_set.collect{|x| x[:singular]}.join("_") + "_" if @nested_set.any?)}#{@controller_build_folder_singular}_path"
816
+ else
817
+ "#{@namespace+"_" if @namespace}#{@controller_build_folder_singular}_path"
887
818
  end
819
+ end
888
820
 
889
- def form_path_edit_helper
890
- HotGlue.optionalized_ternary(namespace: @namespace,
891
- target: @singular,
892
- nested_set: @nested_set,
893
- with_params: true,
894
- put_form: true,
895
- top_level: true)
896
- end
821
+ def path_helper_plural
822
+ HotGlue.optionalized_ternary(namespace: @namespace,
823
+ target: @controller_build_folder,
824
+ nested_set: @nested_set)
825
+ end
897
826
 
827
+ def form_path_new_helper
828
+ HotGlue.optionalized_ternary(namespace: @namespace,
829
+ target: @controller_build_folder,
830
+ nested_set: @nested_set,
831
+ with_params: true,
832
+ top_level: false)
833
+ end
898
834
 
899
- def delete_path_helper
900
- HotGlue.optionalized_ternary(namespace: @namespace,
901
- target: @singular,
902
- nested_set: @nested_set,
903
- with_params: true,
904
- put_form: true)
905
- end
835
+ def form_path_edit_helper
836
+ HotGlue.optionalized_ternary(namespace: @namespace,
837
+ target: @singular,
838
+ nested_set: @nested_set,
839
+ with_params: true,
840
+ put_form: true,
841
+ top_level: true)
842
+ end
906
843
 
907
- def edit_path_helper
908
- HotGlue.optionalized_ternary(namespace: @namespace,
909
- target: @singular,
910
- nested_set: @nested_set,
911
- modifier: "edit_",
912
- with_params: true,
913
- put_form: true)
914
- end
915
844
 
916
- def path_arity
917
- res = ""
918
- if @nested_set.any? && @nested
919
- res << nested_objects_arity + ", "
920
- end
921
- res << "@" + singular
922
- end
845
+ def delete_path_helper
846
+ HotGlue.optionalized_ternary(namespace: @namespace,
847
+ target: @singular,
848
+ nested_set: @nested_set,
849
+ with_params: true,
850
+ put_form: true)
851
+ end
923
852
 
924
- def line_path_partial
925
- "#{@namespace+"/" if @namespace}#{@controller_build_folder}/line"
926
- end
853
+ def edit_path_helper
854
+ HotGlue.optionalized_ternary(namespace: @namespace,
855
+ target: @singular,
856
+ nested_set: @nested_set,
857
+ modifier: "edit_",
858
+ with_params: true,
859
+ put_form: true)
860
+ end
927
861
 
928
- def show_path_partial
929
- "#{@namespace+"/" if @namespace}#{@controller_build_folder}/show"
862
+ def path_arity
863
+ res = ""
864
+ if @nested_set.any? && @nested
865
+ res << nested_objects_arity + ", "
930
866
  end
867
+ res << "@" + singular
868
+ end
931
869
 
932
- def list_path_partial
933
- "#{@namespace+"/" if @namespace}#{@controller_build_folder}/list"
934
- end
870
+ def line_path_partial
871
+ "#{@namespace+"/" if @namespace}#{@controller_build_folder}/line"
872
+ end
935
873
 
936
- def new_path_name
937
- HotGlue.optionalized_ternary(namespace: @namespace,
938
- target: singular,
939
- nested_set: @nested_set,
940
- modifier: "new_",
941
- with_params: true)
942
- end
874
+ def show_path_partial
875
+ "#{@namespace+"/" if @namespace}#{@controller_build_folder}/show"
876
+ end
943
877
 
944
- def nested_assignments
945
- return "" if @nested_set.none?
946
- @nested_set.map{|a| "#{a}: #{a}"}.join(", ") #metaprgramming into Ruby hash
947
- end
878
+ def list_path_partial
879
+ "#{@namespace+"/" if @namespace}#{@controller_build_folder}/list"
880
+ end
948
881
 
949
- def nested_assignments_top_level # this is by accessing the instance variable-- only use at top level
950
- @nested_set.map{|a| "#{a[:singular]}"}.join(", ") #metaprgramming into Ruby hash
951
- end
882
+ def new_path_name
883
+ HotGlue.optionalized_ternary(namespace: @namespace,
884
+ target: singular,
885
+ nested_set: @nested_set,
886
+ modifier: "new_",
887
+ with_params: true)
888
+ end
952
889
 
953
- def nest_assignments_operator(top_level = false, leading_comma = false)
954
- if @nested_set.any?
955
- "#{", " if leading_comma}#{top_level ? nested_assignments_top_level : nested_assignments }"
956
- else
957
- ""
958
- end
959
- end
890
+ def nested_assignments
891
+ return "" if @nested_set.none?
892
+ @nested_set.map{|a| "#{a}: #{a}"}.join(", ") #metaprgramming into Ruby hash
893
+ end
960
894
 
961
- def nested_assignments_with_leading_comma
962
- nest_assignments_operator(false, true)
963
- end
895
+ def nested_assignments_top_level # this is by accessing the instance variable-- only use at top level
896
+ @nested_set.map{|a| "#{a[:singular]}"}.join(", ") #metaprgramming into Ruby hash
897
+ end
964
898
 
965
- def nested_objects_arity
966
- @nested_set.map{|a| "@#{a[:singular]}"}.join(", ")
899
+ def nest_assignments_operator(top_level = false, leading_comma = false)
900
+ if @nested_set.any?
901
+ "#{", " if leading_comma}#{top_level ? nested_assignments_top_level : nested_assignments }"
902
+ else
903
+ ""
967
904
  end
905
+ end
968
906
 
969
- def nested_arity_for_path
970
- [@nested_set[0..-1].collect{|a| "@#{a[:singular]}"}].join(", ") #metaprgramming into arity for the Rails path helper
971
- end
907
+ def nested_assignments_with_leading_comma
908
+ nest_assignments_operator(false, true)
909
+ end
972
910
 
973
- def object_scope
974
- if @auth
975
- if @nested_set.none?
976
- @auth + ".#{plural}"
977
- else
978
- "@" + @nested_set.last[:singular] + ".#{plural}"
979
- end
911
+ def nested_objects_arity
912
+ @nested_set.map{|a| "@#{a[:singular]}"}.join(", ")
913
+ end
914
+
915
+ def nested_arity_for_path
916
+ [@nested_set[0..-1].collect{|a| "@#{a[:singular]}"}].join(", ") #metaprgramming into arity for the Rails path helper
917
+ end
918
+
919
+ def object_scope
920
+ if @auth
921
+ if @nested_set.none?
922
+ @auth + ".#{plural}"
980
923
  else
981
- if @nested_set.none?
982
- @singular_class
983
- else
984
- "@" + @nested_set.last[:singular] + ".#{plural}"
985
- end
924
+ "@" + @nested_set.last[:singular] + ".#{plural}"
925
+ end
926
+ else
927
+ if @nested_set.none?
928
+ @singular_class
929
+ else
930
+ "@" + @nested_set.last[:singular] + ".#{plural}"
986
931
  end
987
932
  end
933
+ end
988
934
 
989
- def all_objects_root
990
- if @auth
991
- if @self_auth
992
- @singular_class + ".where(id: #{@auth}.id)"
993
- elsif @nested_set.none?
994
- @auth + ".#{plural}"
995
- else
996
- "@" + @nested_set.last[:singular] + ".#{plural}"
997
- end
935
+ def all_objects_root
936
+ if @auth
937
+ if @self_auth
938
+ @singular_class + ".where(id: #{@auth}.id)"
939
+ elsif @nested_set.none?
940
+ @auth + ".#{plural}"
998
941
  else
999
- @singular_class + ".all"
942
+ "@" + @nested_set.last[:singular] + ".#{plural}"
1000
943
  end
944
+ else
945
+ @singular_class + ".all"
1001
946
  end
947
+ end
1002
948
 
1003
- def any_nested?
1004
- @nested_set.any?
1005
- end
949
+ def any_nested?
950
+ @nested_set.any?
951
+ end
1006
952
 
1007
- def all_objects_variable
1008
- all_objects_root + ".page(params[:page])"
1009
- end
953
+ def all_objects_variable
954
+ all_objects_root + ".page(params[:page])"
955
+ end
1010
956
 
1011
- def auth_object
1012
- @auth
1013
- end
957
+ def auth_object
958
+ @auth
959
+ end
1014
960
 
1015
- def no_devise_installed
1016
- !Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name }['devise']
1017
- end
961
+ def no_devise_installed
962
+ !Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name }['devise']
963
+ end
1018
964
 
1019
- def magic_button_output
1020
- @template_builder.magic_button_output(
1021
- path: HotGlue.optionalized_ternary(namespace: @namespace,
1022
- target: @singular,
1023
- nested_set: @nested_set,
1024
- with_params: true,
1025
- put_form: true),
1026
- singular: singular,
1027
- magic_buttons: @magic_buttons,
1028
- small_buttons: @small_buttons
1029
- )
1030
- end
965
+ def magic_button_output
966
+ @template_builder.magic_button_output(
967
+ path: HotGlue.optionalized_ternary(namespace: @namespace,
968
+ target: @singular,
969
+ nested_set: @nested_set,
970
+ with_params: true,
971
+ put_form: true),
972
+ singular: singular,
973
+ magic_buttons: @magic_buttons,
974
+ small_buttons: @small_buttons
975
+ )
976
+ end
1031
977
 
1032
- def nav_template
1033
- "#{namespace_with_trailing_dash}nav"
1034
- end
978
+ def nav_template
979
+ "#{namespace_with_trailing_dash}nav"
980
+ end
1035
981
 
1036
- def include_nav_template
1037
- File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_nav.html.#{@markup}")
1038
- end
982
+ def include_nav_template
983
+ File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_nav.html.#{@markup}")
984
+ end
1039
985
 
1040
- def copy_view_files
1041
- return if @specs_only
1042
- all_views.each do |view|
1043
- formats.each do |format|
1044
- source_filename = cc_filename_with_extensions("#{@markup}/#{view}", "#{@markup}")
1045
- dest_filename = cc_filename_with_extensions("#{view}", "#{@markup}")
986
+ def copy_view_files
987
+ return if @specs_only
988
+ all_views.each do |view|
989
+ formats.each do |format|
990
+ source_filename = cc_filename_with_extensions("#{@markup}/#{view}", "#{@markup}")
991
+ dest_filename = cc_filename_with_extensions("#{view}", "#{@markup}")
1046
992
 
1047
993
 
1048
- dest_filepath = File.join("#{filepath_prefix}app/views#{namespace_with_dash}",
1049
- @controller_build_folder, dest_filename)
994
+ dest_filepath = File.join("#{filepath_prefix}app/views#{namespace_with_dash}",
995
+ @controller_build_folder, dest_filename)
1050
996
 
1051
997
 
1052
- template source_filename, dest_filepath
1053
- gsub_file dest_filepath, '\%', '%'
998
+ template source_filename, dest_filepath
999
+ gsub_file dest_filepath, '\%', '%'
1054
1000
 
1055
- end
1056
1001
  end
1002
+ end
1057
1003
 
1058
- turbo_stream_views.each do |view|
1059
- formats.each do |format|
1060
- source_filename = cc_filename_with_extensions( "#{@markup}/#{view}.turbo_stream.#{@markup}")
1061
- dest_filename = cc_filename_with_extensions("#{view}", "turbo_stream.#{@markup}")
1062
- dest_filepath = File.join("#{filepath_prefix}app/views#{namespace_with_dash}",
1063
- @controller_build_folder, dest_filename)
1004
+ turbo_stream_views.each do |view|
1005
+ formats.each do |format|
1006
+ source_filename = cc_filename_with_extensions( "#{@markup}/#{view}.turbo_stream.#{@markup}")
1007
+ dest_filename = cc_filename_with_extensions("#{view}", "turbo_stream.#{@markup}")
1008
+ dest_filepath = File.join("#{filepath_prefix}app/views#{namespace_with_dash}",
1009
+ @controller_build_folder, dest_filename)
1064
1010
 
1065
1011
 
1066
- template source_filename, dest_filepath
1067
- gsub_file dest_filepath, '\%', '%'
1012
+ template source_filename, dest_filepath
1013
+ gsub_file dest_filepath, '\%', '%'
1068
1014
 
1069
- end
1070
1015
  end
1071
1016
  end
1017
+ end
1072
1018
 
1073
- def append_model_callbacks
1074
- # somehow the generator invokes this
1019
+ def append_model_callbacks
1020
+ # somehow the generator invokes this
1075
1021
 
1076
- if options['with_turbo_streams'] == true
1077
- dest_filename = cc_filename_with_extensions("#{singular_class.underscore}", "rb")
1078
- dest_filepath = File.join("#{filepath_prefix}app/models", dest_filename)
1022
+ if options['with_turbo_streams'] == true
1023
+ dest_filename = cc_filename_with_extensions("#{singular_class.underscore}", "rb")
1024
+ dest_filepath = File.join("#{filepath_prefix}app/models", dest_filename)
1079
1025
 
1080
1026
 
1081
- puts "appending turbo callbacks to #{dest_filepath}"
1027
+ puts "appending turbo callbacks to #{dest_filepath}"
1082
1028
 
1083
- text = File.read(dest_filepath)
1029
+ text = File.read(dest_filepath)
1084
1030
 
1085
- append_text = "class #{singular_class} < ApplicationRecord\n"
1086
- if !text.include?("include ActionView::RecordIdentifier")
1087
- append_text << " include ActionView::RecordIdentifier\n"
1088
- end
1089
- append_text << " after_update_commit lambda { broadcast_replace_to self, target: \"#{@namespace}__\#{dom_id(self)}\", partial: \"#{@namespace}/#{@plural}/line\" }\n after_destroy_commit lambda { broadcast_remove_to self, target: \"#{@namespace}__\#{dom_id(self)}\"}\n"
1090
-
1091
- replace = text.gsub(/class #{singular_class} < ApplicationRecord/, append_text)
1092
- File.open(dest_filepath, "w") {|file| file.puts replace}
1031
+ append_text = "class #{singular_class} < ApplicationRecord\n"
1032
+ if !text.include?("include ActionView::RecordIdentifier")
1033
+ append_text << " include ActionView::RecordIdentifier\n"
1093
1034
  end
1094
- end
1035
+ append_text << " after_update_commit lambda { broadcast_replace_to self, target: \"#{@namespace}__\#{dom_id(self)}\", partial: \"#{@namespace}/#{@plural}/line\" }\n after_destroy_commit lambda { broadcast_remove_to self, target: \"#{@namespace}__\#{dom_id(self)}\"}\n"
1095
1036
 
1096
- def namespace_with_dash
1097
- if @namespace
1098
- "/#{@namespace}"
1099
- else
1100
- ""
1101
- end
1037
+ replace = text.gsub(/class #{singular_class} < ApplicationRecord/, append_text)
1038
+ File.open(dest_filepath, "w") {|file| file.puts replace}
1102
1039
  end
1040
+ end
1103
1041
 
1104
- def namespace_with_trailing_dash
1105
- @namespace ? "#{@namespace}/" : ""
1042
+ def namespace_with_dash
1043
+ if @namespace
1044
+ "/#{@namespace}"
1045
+ else
1046
+ ""
1106
1047
  end
1048
+ end
1107
1049
 
1108
- def all_views
1109
- res = %w(index _line _list _show _errors)
1110
-
1111
- unless @no_create
1112
- res += %w(new _new_form _new_button)
1113
- end
1050
+ def namespace_with_trailing_dash
1051
+ @namespace ? "#{@namespace}/" : ""
1052
+ end
1114
1053
 
1115
- unless @no_edit
1116
- res << 'edit'
1117
- end
1054
+ def all_views
1055
+ res = %w(index _line _list _show)
1118
1056
 
1119
- if !( @no_edit && @no_create)
1120
- res << '_form'
1121
- end
1122
- res
1057
+ unless @no_create
1058
+ res += %w(new _new_form _new_button)
1123
1059
  end
1124
1060
 
1125
- def turbo_stream_views
1126
- res = []
1127
- unless @no_delete
1128
- res << 'destroy'
1129
- end
1130
-
1131
- unless @no_create
1132
- res << 'create'
1133
- end
1134
-
1135
- unless @no_edit
1136
- res << 'edit'
1137
- res << 'update'
1138
- end
1139
-
1140
- res
1061
+ unless @no_edit
1062
+ res += %w{edit _edit}
1141
1063
  end
1142
1064
 
1143
- def handler
1144
- :erb
1065
+ if !( @no_edit && @no_create)
1066
+ res << '_form'
1145
1067
  end
1068
+ res
1069
+ end
1146
1070
 
1147
- def model_has_strings?
1148
- false
1071
+ def turbo_stream_views
1072
+ res = []
1073
+ unless @no_delete
1074
+ res << 'destroy'
1149
1075
  end
1150
1076
 
1151
- def model_search_fields # an array of fields we can search on
1152
- []
1077
+ unless @no_create
1078
+ res << 'create'
1153
1079
  end
1154
1080
 
1155
- def form_fields_html
1156
- @template_builder.all_form_fields(layout_strategy: @layout_strategy,
1157
- layout_object: @layout_object)
1081
+ unless @no_edit
1082
+ res << 'edit'
1083
+ res << 'update'
1158
1084
  end
1159
1085
 
1160
- def list_label
1161
- @list_label_heading
1162
- end
1086
+ res
1087
+ end
1163
1088
 
1164
- def new_thing_label
1165
- @new_thing_label
1166
- end
1089
+ def handler
1090
+ :erb
1091
+ end
1167
1092
 
1168
- def all_line_fields
1169
- @template_builder.all_line_fields(
1170
- col_identifier: @layout_strategy.column_classes_for_line_fields,
1171
- perc_width: @layout_strategy.each_col, #undefined method `each_col'
1172
- layout_strategy: @layout_strategy,
1173
- layout_object: @layout_object
1174
- )
1093
+ def model_has_strings?
1094
+ false
1095
+ end
1096
+
1097
+ def model_search_fields # an array of fields we can search on
1098
+ []
1099
+ end
1100
+
1101
+ def form_fields_html
1102
+ @template_builder.all_form_fields(layout_strategy: @layout_strategy,
1103
+ layout_object: @layout_object)
1104
+ end
1105
+
1106
+ def list_label
1107
+ @list_label_heading
1108
+ end
1109
+
1110
+ def new_thing_label
1111
+ @new_thing_label
1112
+ end
1113
+
1114
+ def all_line_fields
1115
+ @template_builder.all_line_fields(
1116
+ col_identifier: @layout_strategy.column_classes_for_line_fields,
1117
+ perc_width: @layout_strategy.each_col, #undefined method `each_col'
1118
+ layout_strategy: @layout_strategy,
1119
+ layout_object: @layout_object
1120
+ )
1121
+ end
1122
+
1123
+ def controller_descends_from
1124
+ if defined?(@namespace.titlecase.gsub(" ", "") + "::BaseController")
1125
+ @namespace.titlecase.gsub(" ", "") + "::BaseController"
1126
+ else
1127
+ "ApplicationController"
1175
1128
  end
1129
+ end
1176
1130
 
1177
- def controller_descends_from
1178
- if defined?(@namespace.titlecase.gsub(" ", "") + "::BaseController")
1179
- @namespace.titlecase.gsub(" ", "") + "::BaseController"
1131
+ def display_class
1132
+ me = eval(singular_class)
1133
+
1134
+ @display_class ||=
1135
+ if me.column_names.include?("name") || me.instance_methods(false).include?(:name)
1136
+ # note that all class object respond_to?(:name) with the name of their own class
1137
+ # this one is unique
1138
+ "name"
1139
+ elsif me.column_names.include?("to_label") || me.instance_methods(false).include?(:to_label)
1140
+ "to_label"
1141
+ elsif me.column_names.include?("full_name") || me.instance_methods(false).include?(:full_name)
1142
+ "full_name"
1143
+ elsif me.column_names.include?("display_name") || me.instance_methods(false).include?(:display_name)
1144
+ "display_name"
1145
+ elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
1146
+ "email"
1180
1147
  else
1181
- "ApplicationController"
1148
+ 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)"
1149
+ raise(HotGlue::Error, exit_message)
1182
1150
  end
1183
- end
1184
-
1185
- def display_class
1186
- me = eval(singular_class)
1187
-
1188
- @display_class ||=
1189
- if me.column_names.include?("name") || me.instance_methods(false).include?(:name)
1190
- # note that all class object respond_to?(:name) with the name of their own class
1191
- # this one is unique
1192
- "name"
1193
- elsif me.column_names.include?("to_label") || me.instance_methods(false).include?(:to_label)
1194
- "to_label"
1195
- elsif me.column_names.include?("full_name") || me.instance_methods(false).include?(:full_name)
1196
- "full_name"
1197
- elsif me.column_names.include?("display_name") || me.instance_methods(false).include?(:display_name)
1198
- "display_name"
1199
- elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
1200
- "email"
1201
- else
1202
- 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)"
1203
- raise(HotGlue::Error, exit_message)
1204
- end
1205
- end
1151
+ end
1206
1152
 
1207
- def destroy_action
1208
- return false if @self_auth
1209
- return !@no_delete
1210
- end
1153
+ def destroy_action
1154
+ return false if @self_auth
1155
+ return !@no_delete
1156
+ end
1211
1157
 
1212
- def create_action
1213
- return false if @self_auth
1214
- return !@no_create
1215
- end
1158
+ def create_action
1159
+ return false if @self_auth
1160
+ return !@no_create
1161
+ end
1216
1162
 
1217
- def namespace_with_slash
1218
- if @namespace
1219
- "#{@namespace}/"
1220
- else
1221
- ""
1222
- end
1163
+ def namespace_with_slash
1164
+ if @namespace
1165
+ "#{@namespace}/"
1166
+ else
1167
+ ""
1223
1168
  end
1169
+ end
1224
1170
 
1225
- def paginate
1226
- @template_builder.paginate(plural: plural)
1227
- end
1171
+ def paginate
1172
+ @template_builder.paginate(plural: plural)
1173
+ end
1228
1174
 
1229
- def controller_magic_button_update_actions
1230
- @magic_buttons.collect{ |magic_button|
1231
- " if #{singular}_params[:#{magic_button}]
1175
+ def controller_magic_button_update_actions
1176
+ @magic_buttons.collect{ |magic_button|
1177
+ " if #{singular}_params[:#{magic_button}]
1232
1178
  begin
1233
1179
  res = @#{singular}.#{magic_button}!
1234
1180
  res = \"#{magic_button.titleize}ed.\" if res === true
@@ -1239,79 +1185,96 @@ module HotGlue
1239
1185
  end
1240
1186
  end"
1241
1187
 
1242
- }.join("\n") + "\n"
1243
- end
1188
+ }.join("\n") + "\n"
1189
+ end
1244
1190
 
1245
1191
 
1246
- def controller_update_params_tap_away_magic_buttons
1247
- @magic_buttons.collect{ |magic_button|
1248
- ".tap{ |ary| ary.delete('__#{magic_button}') }"
1249
- }.join("")
1250
- end
1192
+ def controller_update_params_tap_away_magic_buttons
1193
+ @magic_buttons.collect{ |magic_button|
1194
+ ".tap{ |ary| ary.delete('__#{magic_button}') }"
1195
+ }.join("")
1196
+ end
1251
1197
 
1252
- def controller_update_params_tap_away_alt_lookups
1253
- @alt_lookups.collect{ |key, data|
1254
- ".tap{ |ary| ary.delete('__lookup_#{data[:lookup_as]}') }"
1255
- }.join("")
1256
- end
1198
+ def controller_update_params_tap_away_alt_lookups
1199
+ @alt_lookups.collect{ |key, data|
1200
+ ".tap{ |ary| ary.delete('__lookup_#{data[:lookup_as]}') }"
1201
+ }.join("")
1202
+ end
1257
1203
 
1258
- def nested_for_turbo_id_list_constructor
1259
- if @nested_set.any?
1260
- '+ (((\'__\' + nested_for) if defined?(nested_for)) || "")'
1261
- else
1262
- ""
1263
- end
1204
+ def nested_for_turbo_id_list_constructor
1205
+ if @nested_set.any?
1206
+ '+ (((\'__\' + nested_for) if defined?(nested_for)) || "")'
1207
+ else
1208
+ ""
1264
1209
  end
1210
+ end
1265
1211
 
1266
- def n_plus_one_includes
1267
- if @associations.any? || @attachments.any?
1268
- ".includes(" + (@associations.map{|x| x} + @attachments.collect{|k,v| "#{k}_attachment"}).map{|x| ":#{x.to_s}"}.join(", ") + ")"
1269
- else
1270
- ""
1271
- end
1212
+ def n_plus_one_includes
1213
+ if @associations.any? || @attachments.any?
1214
+ ".includes(" + (@associations.map{|x| x} + @attachments.collect{|k,v| "#{k}_attachment"}).map{|x| ":#{x.to_s}"}.join(", ") + ")"
1215
+ else
1216
+ ""
1272
1217
  end
1218
+ end
1273
1219
 
1274
- def nested_for_turbo_nested_constructor(top_level = true)
1275
- instance_symbol = "@" if top_level
1276
- instance_symbol = "" if !top_level
1277
- if @nested_set.none?
1278
- "\"\""
1279
- else
1280
- @nested_set.collect{|arg|
1281
- "(((\"__#{arg[:singular]}-\#{" + "@" + arg[:singular] + ".id}\") if @" + arg[:singular] + ") || \"\")"
1282
- }.join(" + ")
1283
- end
1220
+ def nested_for_turbo_nested_constructor(top_level = true)
1221
+ instance_symbol = "@" if top_level
1222
+ instance_symbol = "" if !top_level
1223
+ if @nested_set.none?
1224
+ "\"\""
1225
+ else
1226
+ @nested_set.collect{|arg|
1227
+ "(((\"__#{arg[:singular]}-\#{" + "@" + arg[:singular] + ".id}\") if @" + arg[:singular] + ") || \"\")"
1228
+ }.join(" + ")
1284
1229
  end
1230
+ end
1285
1231
 
1286
- def nested_for_assignments_constructor(top_level = true)
1287
- instance_symbol = "@" if top_level
1288
- instance_symbol = "" if !top_level
1289
- if @nested_set.none?
1290
- ""
1291
- else
1292
- ", \n nested_for: \"" + @nested_set.collect{|a| "#{a[:singular]}-" + '#{' + instance_symbol + a[:singular] + ".id}"}.join("__") + "\""
1293
- end
1232
+ def nested_for_assignments_constructor(top_level = true)
1233
+ instance_symbol = "@" if top_level
1234
+ instance_symbol = "" if !top_level
1235
+ if @nested_set.none?
1236
+ ""
1237
+ else
1238
+ ", \n nested_for: \"" + @nested_set.collect{|a| "#{a[:singular]}-" + '#{' + instance_symbol + a[:singular] + ".id}"}.join("__") + "\""
1294
1239
  end
1240
+ end
1295
1241
 
1296
- private # thor does something fancy like sending the class all of its own methods during some strange run sequence
1297
- # does not like public methods
1298
- def cc_filename_with_extensions(name, file_format = format)
1299
- [name, file_format].compact.join(".")
1300
- end
1242
+ private # thor does something fancy like sending the class all of its own methods during some strange run sequence
1243
+ # does not like public methods
1244
+ def cc_filename_with_extensions(name, file_format = format)
1245
+ [name, file_format].compact.join(".")
1246
+ end
1301
1247
 
1302
- def hawk_to_ruby
1303
- res = @hawk_keys.collect{ |k,v|
1304
- "#{k.to_s}: [#{v[:bind_to].join(".")}]"
1305
- }.join(", ")
1306
- res
1307
- end
1248
+ def hawk_to_ruby
1249
+ res = @hawk_keys.collect{ |k,v|
1250
+ "#{k.to_s}: [#{v[:bind_to].join(".")}]"
1251
+ }.join(", ")
1252
+ res
1253
+ end
1308
1254
 
1309
- def controller_attachment_orig_filename_pickup_syntax
1310
- @attachments.collect{ |key, attachment| "\n" + " modified_params[:#{ attachment[:field_for_original_filename] }] = #{singular}_params['#{ key }'].original_filename" if attachment[:field_for_original_filename] }.compact.join("\n")
1311
- end
1255
+ def controller_attachment_orig_filename_pickup_syntax
1256
+ @attachments.collect{ |key, attachment| "\n" + " modified_params[:#{ attachment[:field_for_original_filename] }] = #{singular}_params['#{ key }'].original_filename" if attachment[:field_for_original_filename] }.compact.join("\n")
1257
+ end
1312
1258
 
1313
- def any_datetime_fields?
1314
- (@columns - @attachments.keys.collect(&:to_sym)).collect{|col| eval("#{singular_class}.columns_hash['#{col}']").type}.include?(:datetime)
1259
+ def any_datetime_fields?
1260
+ (@columns - @attachments.keys.collect(&:to_sym)).collect{|col| eval("#{singular_class}.columns_hash['#{col}']").type}.include?(:datetime)
1261
+ end
1262
+
1263
+ def post_action_parental_updates
1264
+ if @nested_set.any?
1265
+ "\n" + @nested_set.collect{ |data|
1266
+ parent = data[:singular]
1267
+ "@#{singular}.#{parent}.reload"
1268
+ }.join("\n")
1315
1269
  end
1316
1270
  end
1271
+
1272
+
1273
+ def turbo_parental_updates
1274
+ @nested_set.collect{| data|
1275
+ "<%= turbo_stream.replace \"#{@namespace + '__' if @namespace}\#{dom_id(@#{data[:singular]})}\" do %>
1276
+ <%= render partial: \"#{@namespace}/#{data[:plural]}/edit\", locals: {#{data[:singular]}: @#{singular}.#{data[:singular]}.reload} %>
1277
+ <% end %>"
1278
+ }.join("\n")
1279
+ end
1317
1280
  end