hot-glue 0.5.1 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +16 -0
- data/.gitignore +3 -1
- data/.ruby-version +1 -0
- data/.travis.yml +2 -2
- data/Gemfile +18 -7
- data/LICENSE +2 -16
- data/README.md +110 -73
- data/README2.md +0 -2
- data/app/helpers/hot_glue/controller_helper.rb +34 -26
- data/config/database.yml +21 -7
- data/db/schema.rb +149 -0
- data/lib/generators/hot_glue/install_generator.rb +1 -55
- data/lib/generators/hot_glue/markup_templates/erb.rb +15 -10
- data/lib/generators/hot_glue/scaffold_generator.rb +219 -138
- data/lib/generators/hot_glue/templates/capybara_login.rb +1 -1
- data/lib/generators/hot_glue/templates/controller.rb.erb +22 -21
- data/lib/generators/hot_glue/templates/erb/_new_button.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/_show.erb +1 -1
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +8 -123
- data/lib/hotglue/version.rb +1 -1
- data/script/clean_generated_code +20 -0
- data/script/test +47 -0
- metadata +10 -8
- data/.circleci/config.yml +0 -71
- data/Gemfile.lock +0 -230
- data/Rakefile +0 -42
- data/bin/rails +0 -14
- data/db/schema.rb +0 -1
@@ -68,19 +68,18 @@ module HotGlue
|
|
68
68
|
def self.derrive_reference_name(thing_as_string)
|
69
69
|
assoc_class = eval(thing_as_string)
|
70
70
|
|
71
|
-
if assoc_class.respond_to?("name")
|
71
|
+
if assoc_class.new.respond_to?("name")
|
72
72
|
display_column = "name"
|
73
|
-
elsif assoc_class.respond_to?("to_label")
|
73
|
+
elsif assoc_class.new.respond_to?("to_label")
|
74
74
|
display_column = "to_label"
|
75
|
-
elsif assoc_class.respond_to?("full_name")
|
75
|
+
elsif assoc_class.new.respond_to?("full_name")
|
76
76
|
display_column = "full_name"
|
77
|
-
elsif assoc_class.respond_to?("display_name")
|
77
|
+
elsif assoc_class.new.respond_to?("display_name")
|
78
78
|
display_column = "display_name"
|
79
|
-
elsif assoc_class.respond_to?("email")
|
79
|
+
elsif assoc_class.new.respond_to?("email")
|
80
80
|
display_column = "email"
|
81
|
-
else
|
82
|
-
|
83
|
-
# puts "*** Oops: Can't find any column to use as the display label for the #{assoc.name.to_s} association on the #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, or 5) email directly on your #{assoc.class_name} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
|
81
|
+
# else # SHOULD BE UNREACHABLE
|
82
|
+
# raise("this should have been caught by the checker in the initializer")
|
84
83
|
end
|
85
84
|
display_column
|
86
85
|
end
|
@@ -123,6 +122,7 @@ module HotGlue
|
|
123
122
|
class_option :smart_layout, type: :boolean, default: false
|
124
123
|
class_option :markup, type: :string, default: nil # deprecated -- use in app config instead
|
125
124
|
class_option :layout, type: :string, default: nil # if used here it will override what is in the config
|
125
|
+
class_option :hawk, type: :string, default: nil #
|
126
126
|
|
127
127
|
class_option :no_list_label, type: :boolean, default: false
|
128
128
|
|
@@ -130,8 +130,8 @@ module HotGlue
|
|
130
130
|
|
131
131
|
|
132
132
|
# determines if the labels show up BEFORE or AFTER on the NEW/EDIT (form)
|
133
|
-
class_option :form_labels_position, default: 'after' # choices are before, after, omit
|
134
|
-
class_option :form_placeholder_labels, default: false # puts the field names into the placeholder labels
|
133
|
+
class_option :form_labels_position, type: :string, default: 'after' # choices are before, after, omit
|
134
|
+
class_option :form_placeholder_labels, type: :boolean, default: false # puts the field names into the placeholder labels
|
135
135
|
|
136
136
|
|
137
137
|
# NOT YET IMPLEMENTED
|
@@ -149,8 +149,9 @@ module HotGlue
|
|
149
149
|
raise(HotGlue::Error, message)
|
150
150
|
end
|
151
151
|
|
152
|
-
|
153
|
-
|
152
|
+
|
153
|
+
if options['specs_only'] && options['no_specs']
|
154
|
+
raise(HotGlue::Error, "*** Oops: You seem to have specified both the --specs-only flag and --no-specs flags. this doesn't make any sense, so I am aborting. Aborting.")
|
154
155
|
end
|
155
156
|
|
156
157
|
if !options['exclude'].empty? && !options['include'].empty?
|
@@ -162,20 +163,16 @@ module HotGlue
|
|
162
163
|
|
163
164
|
|
164
165
|
if @stimulus_syntax.nil?
|
165
|
-
|
166
|
-
@stimulus_syntax = true
|
167
|
-
else
|
168
|
-
@stimulus_syntax = false
|
169
|
-
end
|
170
|
-
end
|
166
|
+
@stimulus_syntax = true
|
171
167
|
|
172
|
-
|
173
|
-
|
174
|
-
|
168
|
+
# if Rails.version.split(".")[0].to_i >= 7
|
169
|
+
# @stimulus_syntax = true
|
170
|
+
# else
|
171
|
+
# end
|
175
172
|
end
|
176
173
|
|
177
174
|
if !options['markup'].nil?
|
178
|
-
message = "Using --
|
175
|
+
message = "Using --markup flag in the generator is deprecated; instead, use a file at config/hot_glue.yml with a key markup set to `erb` or `haml`"
|
179
176
|
raise(HotGlue::Error, message)
|
180
177
|
end
|
181
178
|
|
@@ -185,12 +182,10 @@ module HotGlue
|
|
185
182
|
if @markup == "erb"
|
186
183
|
@template_builder = HotGlue::ErbTemplate.new
|
187
184
|
elsif @markup == "slim"
|
188
|
-
|
189
|
-
raise(HotGlue::Error, message)
|
190
|
-
@template_builder = HotGlue::SlimTemplate.new
|
191
|
-
|
185
|
+
raise(HotGlue::Error, "SLIM IS NOT IMPLEMENTED")
|
192
186
|
elsif @markup == "haml"
|
193
|
-
|
187
|
+
raise(HotGlue::Error, "HAML IS NOT IMPLEMENTED")
|
188
|
+
|
194
189
|
end
|
195
190
|
|
196
191
|
|
@@ -225,7 +220,7 @@ module HotGlue
|
|
225
220
|
@controller_build_folder_singular = singular
|
226
221
|
|
227
222
|
if ! @controller_build_folder.ends_with?("s")
|
228
|
-
raise "can't build with controller name #{@controller_build_folder} because it doesn't end with an 's'"
|
223
|
+
raise HotGlue::Error, "can't build with controller name #{@controller_build_folder} because it doesn't end with an 's'"
|
229
224
|
end
|
230
225
|
|
231
226
|
@auth = options['auth'] || "current_user"
|
@@ -234,7 +229,7 @@ module HotGlue
|
|
234
229
|
|
235
230
|
|
236
231
|
if options['nest']
|
237
|
-
raise "STOP: the flag --nest has been replaced with --nested; please re-run using the --nested flag"
|
232
|
+
raise HotGlue::Error, "STOP: the flag --nest has been replaced with --nested; please re-run using the --nested flag"
|
238
233
|
|
239
234
|
end
|
240
235
|
|
@@ -275,7 +270,8 @@ module HotGlue
|
|
275
270
|
|
276
271
|
@form_labels_position = options['form_labels_position']
|
277
272
|
if !['before','after','omit'].include?(@form_labels_position)
|
278
|
-
|
273
|
+
|
274
|
+
raise HotGlue::Error, "You passed '#{@form_labels_position}' as the setting for --form-labels-position but the only allowed options are before, after (default), and omit"
|
279
275
|
end
|
280
276
|
|
281
277
|
@form_placeholder_labels = options['form_placeholder_labels'] # true or false
|
@@ -283,7 +279,7 @@ module HotGlue
|
|
283
279
|
|
284
280
|
|
285
281
|
if !['before','after','omit'].include?(@inline_list_labels)
|
286
|
-
raise "You passed '#{@inline_list_labels}' as the setting for --inline-list-labels but the only allowed options are before, after, and omit (default)"
|
282
|
+
raise HotGlue::Error, "You passed '#{@inline_list_labels}' as the setting for --inline-list-labels but the only allowed options are before, after, and omit (default)"
|
287
283
|
end
|
288
284
|
|
289
285
|
|
@@ -292,7 +288,7 @@ module HotGlue
|
|
292
288
|
@smart_layout = options['smart_layout']
|
293
289
|
|
294
290
|
if options['include'].include?(":") && @smart_layout
|
295
|
-
raise "You specified both --smart-layout and also specified grouping mode (there is a : character in your field include list); you must remove the colon(s) from your --include tag or remove the --smart-layout option"
|
291
|
+
raise HotGlue::Error, "You specified both --smart-layout and also specified grouping mode (there is a : character in your field include list); you must remove the colon(s) from your --include tag or remove the --smart-layout option"
|
296
292
|
end
|
297
293
|
|
298
294
|
|
@@ -320,9 +316,24 @@ module HotGlue
|
|
320
316
|
raise "This controller appears to be the same as the authentication object but in this context you cannot build a new/create action; please re-run with --no-create flag"
|
321
317
|
end
|
322
318
|
|
323
|
-
|
324
|
-
|
319
|
+
@magic_buttons = []
|
320
|
+
if options['magic_buttons']
|
321
|
+
@magic_buttons = options['magic_buttons'].split(',')
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
@small_buttons = options['small_buttons'] || false
|
326
|
+
|
327
|
+
@build_update_action = !@no_edit || !@magic_buttons.empty?
|
328
|
+
# if the magic buttons are present, build the update action anyway
|
325
329
|
|
330
|
+
@ujs_syntax = options['ujs_syntax']
|
331
|
+
if !@ujs_syntax
|
332
|
+
@ujs_syntax = !defined?(Turbo::Engine)
|
333
|
+
end
|
334
|
+
|
335
|
+
|
336
|
+
# NEST CHAIN
|
326
337
|
# new syntax
|
327
338
|
# @nested_set = [
|
328
339
|
# {
|
@@ -333,10 +344,6 @@ module HotGlue
|
|
333
344
|
@nested_set = []
|
334
345
|
|
335
346
|
if ! @nested.nil?
|
336
|
-
|
337
|
-
|
338
|
-
@nested_args = @nested.split("/").collect{|x| x.gsub("~","")}
|
339
|
-
|
340
347
|
@nested_set = @nested.split("/").collect { |arg|
|
341
348
|
is_optional = arg.start_with?("~")
|
342
349
|
arg.gsub!("~","")
|
@@ -347,57 +354,51 @@ module HotGlue
|
|
347
354
|
}
|
348
355
|
|
349
356
|
}
|
350
|
-
|
351
|
-
puts "@nested_set is #{@nested_set}"
|
352
|
-
@nested_args_plural = {}
|
353
|
-
|
354
|
-
|
355
|
-
@nested_args.each do |a|
|
356
|
-
@nested_args_plural[a] = a + "s"
|
357
|
-
end
|
357
|
+
puts "NESTING: #{@nested_set}"
|
358
358
|
end
|
359
359
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
@build_update_action = !@no_edit || !@magic_buttons.empty?
|
369
|
-
# if the magic buttons are present, build the update action anyway
|
360
|
+
# OBJECT OWNERSHIP & NESTING
|
361
|
+
@reference_name = HotGlue.derrive_reference_name(singular_class)
|
362
|
+
if @auth && @self_auth
|
363
|
+
# byebug
|
364
|
+
@object_owner_sym = @auth.gsub("current_", "").to_sym
|
365
|
+
@object_owner_eval = @auth
|
366
|
+
@object_owner_optional = false
|
367
|
+
@object_owner_name = @auth.gsub("current_", "").to_s
|
370
368
|
|
371
369
|
|
372
|
-
|
370
|
+
elsif @auth && ! @self_auth && @nested_set.none? && !@auth.include?(".")
|
371
|
+
# byebug
|
373
372
|
@object_owner_sym = @auth.gsub("current_", "").to_sym
|
374
373
|
@object_owner_eval = @auth
|
375
374
|
@object_owner_optional = false
|
376
|
-
|
375
|
+
@object_owner_name = @auth.gsub("current_", "").to_s
|
377
376
|
|
378
|
-
|
377
|
+
elsif @auth && @auth.include?(".")
|
378
|
+
# byebug
|
379
|
+
@object_owner_sym = nil
|
380
|
+
@object_owner_eval = @auth
|
381
|
+
else
|
382
|
+
# byebug
|
383
|
+
if @nested_set.any?
|
379
384
|
@object_owner_sym = @nested_set.last[:singular].to_sym
|
380
385
|
@object_owner_eval = "@#{@nested_set.last[:singular]}"
|
381
386
|
@object_owner_name = @nested_set.last[:singular]
|
382
387
|
@object_owner_optional = @nested_set.last[:optional]
|
383
388
|
else
|
384
|
-
@object_owner_sym =
|
389
|
+
@object_owner_sym = nil
|
385
390
|
@object_owner_eval = ""
|
386
391
|
end
|
387
392
|
end
|
388
393
|
|
394
|
+
identify_object_owner
|
395
|
+
setup_hawk_keys
|
389
396
|
|
390
|
-
@ujs_syntax = options['ujs_syntax']
|
391
397
|
|
392
|
-
if !@ujs_syntax
|
393
|
-
@ujs_syntax = !defined?(Turbo::Engine)
|
394
|
-
end
|
395
|
-
@reference_name = HotGlue.derrive_reference_name(singular_class)
|
396
398
|
|
397
|
-
|
399
|
+
# SETUP FIELDS & LAYOUT
|
398
400
|
setup_fields
|
399
|
-
|
400
|
-
if (@columns - @show_only - (@object_owner_sym.empty? ? [] : [@ownership_field.to_sym])).empty?
|
401
|
+
if (@columns - @show_only - (@ownership_field ? [@ownership_field.to_sym] : [])).empty?
|
401
402
|
@no_field_form = true
|
402
403
|
end
|
403
404
|
|
@@ -412,41 +413,61 @@ module HotGlue
|
|
412
413
|
})
|
413
414
|
@layout_object = builder.construct
|
414
415
|
|
415
|
-
@menu_file_exists = true if @
|
416
|
+
@menu_file_exists = true if @nested_set.none? && File.exists?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
|
417
|
+
|
416
418
|
|
417
419
|
end
|
418
420
|
|
421
|
+
def setup_hawk_keys
|
422
|
+
@hawk_keys = {}
|
423
|
+
|
424
|
+
if options['hawk']
|
425
|
+
options['hawk'].split(",").each do |hawk_entry|
|
426
|
+
# format is: abc_id[thing]
|
427
|
+
|
428
|
+
if hawk_entry.include?("{")
|
429
|
+
hawk_entry =~ /(.*){(.*)}/
|
430
|
+
key, hawk_to = $1, $2
|
431
|
+
else
|
432
|
+
key = hawk_entry
|
433
|
+
hawk_to = @auth
|
434
|
+
end
|
435
|
+
hawk_scope = key.gsub("_id", "").pluralize
|
436
|
+
@hawk_keys[key.to_sym] = [hawk_to, hawk_scope]
|
437
|
+
end
|
438
|
+
|
439
|
+
puts "HAWKING: #{@hawk_keys}"
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
419
443
|
def identify_object_owner
|
420
444
|
auth_assoc = @auth && @auth.gsub("current_","")
|
421
445
|
|
422
|
-
if
|
446
|
+
if @object_owner_sym && ! @self_auth
|
423
447
|
auth_assoc_field = auth_assoc + "_id" unless @god
|
424
|
-
|
425
448
|
assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
|
426
|
-
|
449
|
+
# byebug
|
427
450
|
if assoc
|
428
451
|
@ownership_field = assoc.name.to_s + "_id"
|
429
|
-
elsif ! @
|
430
|
-
|
431
|
-
exit_message = "*** Oops: It looks like is no association from class called #{@singular_class} to the current_#{@object_owner_sym}. If your user is called something else, pass with flag auth=current_X where X is the model for your users as lowercase. Also, be sure to implement current_X as a method on your controller. (If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for auth_identifier.) To make a controller that can read all records, specify with --god."
|
452
|
+
elsif ! @nested_set.any?
|
453
|
+
exit_message = "*** Oops: It looks like is no association `#{@object_owner_sym}` from the object #{@singular_class}. If your user is called something else, pass with flag auth=current_X where X is the model for your users as lowercase. Also, be sure to implement current_X as a method on your controller. (If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for auth_identifier.) To make a controller that can read all records, specify with --god."
|
432
454
|
raise(HotGlue::Error, exit_message)
|
433
455
|
|
434
456
|
else
|
435
|
-
|
436
457
|
if eval(singular_class + ".reflect_on_association(:#{@object_owner_sym.to_s})").nil? && !eval(singular_class + ".reflect_on_association(:#{@object_owner_sym.to_s.singularize})").nil?
|
437
458
|
exit_message = "*** Oops: you tried to nest #{singular_class} within a route for `#{@object_owner_sym}` but I can't find an association for this relationship. Did you mean `#{@object_owner_sym.to_s.singularize}` (singular) instead?"
|
438
|
-
else
|
439
|
-
|
459
|
+
# else # NOTE: not reachable
|
460
|
+
# exit_message = "*** Oops: Missing relationship from class #{singular_class} to :#{@object_owner_sym} maybe add `belongs_to :#{@object_owner_sym}` to #{singular_class}\n (If your user is called something else, pass with flag auth=current_X where X is the model for your auth object as lowercase. Also, be sure to implement current_X as a method on your controller. If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for --auth-identifier flag). To make a controller that can read all records, specify with --god."
|
440
461
|
end
|
441
462
|
|
442
463
|
raise(HotGlue::Error, exit_message)
|
443
464
|
end
|
465
|
+
elsif @object_owner_sym && ! @object_owner_eval.include?(".")
|
466
|
+
@ownership_field = @object_owner_name + "_id"
|
444
467
|
end
|
445
468
|
end
|
446
469
|
|
447
|
-
|
448
470
|
def setup_fields
|
449
|
-
auth_assoc = @auth && @auth.gsub("current_","")
|
450
471
|
|
451
472
|
if !@include_fields
|
452
473
|
@exclude_fields.push :id, :created_at, :updated_at, :encrypted_password,
|
@@ -455,7 +476,6 @@ module HotGlue
|
|
455
476
|
:confirmation_token, :confirmed_at,
|
456
477
|
:confirmation_sent_at, :unconfirmed_email
|
457
478
|
|
458
|
-
@exclude_fields.push( (auth_assoc + "_id").to_sym) if ! auth_assoc.nil?
|
459
479
|
@exclude_fields.push( @ownership_field.to_sym ) if ! @ownership_field.nil?
|
460
480
|
|
461
481
|
|
@@ -477,30 +497,34 @@ module HotGlue
|
|
477
497
|
assoc_name = col.to_s.gsub("_id","")
|
478
498
|
|
479
499
|
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
exit_message = "*** Oops: The model #{singular_class} is missing an association for :#{assoc_name} or the model #{assoc_name.titlecase} doesn't exist. TODO: Please implement a model for #{assoc_name.titlecase};
|
500
|
+
assoc_model = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
501
|
+
|
502
|
+
if assoc_model.nil?
|
503
|
+
exit_message = "*** Oops: The model #{singular_class} is missing an association for :#{assoc_name} or the model #{assoc_name.titlecase} doesn't exist. TODO: Please implement a model for #{assoc_name.titlecase}; or add to #{singular_class} `belongs_to :#{assoc_name}`. To make a controller that can read all records, specify with --god."
|
484
504
|
puts exit_message
|
485
505
|
raise(HotGlue::Error, exit_message)
|
486
506
|
end
|
487
507
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
508
|
+
begin
|
509
|
+
assoc_class = eval(assoc_model.try(:class_name))
|
510
|
+
@associations << assoc_name.to_sym
|
511
|
+
name_list = [:name, :to_label, :full_name, :display_name, :email]
|
512
|
+
|
513
|
+
rescue
|
514
|
+
# unreachable(?)
|
515
|
+
# if eval("#{singular_class}.reflect_on_association(:#{assoc_name.singularize})")
|
516
|
+
# raise(HotGlue::Error,"*** Oops: #{singular_class} has no association for #{assoc_name.singularize}")
|
517
|
+
# else
|
518
|
+
# raise(HotGlue::Error,"*** Oops: Missing relationship from class #{singular_class} to :#{@object_owner_sym} maybe add `belongs_to :#{@object_owner_sym}` to #{singular_class}\n (If your user is called something else, pass with flag auth=current_X where X is the model for your auth object as lowercase. Also, be sure to implement current_X as a method on your controller. If you really don't want to implement a current_X on your controller and want me to check some other method for your current user, see the section in the docs for --auth-identifier flag). To make a controller that can read all records, specify with --god.")
|
519
|
+
# end
|
493
520
|
end
|
494
521
|
|
495
|
-
|
496
|
-
assoc_class = eval(assoc_model.name)
|
497
|
-
name_list = [:name, :to_label, :full_name, :display_name, :email]
|
498
|
-
if name_list.collect{ |field|
|
522
|
+
if assoc_class && name_list.collect{ |field|
|
499
523
|
assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
|
500
524
|
}.any?
|
501
525
|
# do nothing here
|
502
526
|
else
|
503
|
-
exit_message = "
|
527
|
+
exit_message = "Oops: Missing a label for `#{assoc_class}`. Can't find any column to use as the display label for the #{assoc_name} association on the #{singular_class} model. TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name 5) email. You can implement any of these directly on your`#{assoc_class}` model (can be database fields or model methods) or alias them to field you want to use as your display label. Then RERUN THIS GENERATOR. (Field used will be chosen based on rank here.)"
|
504
528
|
raise(HotGlue::Error,exit_message)
|
505
529
|
end
|
506
530
|
end
|
@@ -508,6 +532,11 @@ module HotGlue
|
|
508
532
|
end
|
509
533
|
end
|
510
534
|
|
535
|
+
|
536
|
+
def auth_root
|
537
|
+
"authenticate_" + @auth_identifier.split(".")[0] + "!"
|
538
|
+
end
|
539
|
+
|
511
540
|
def formats
|
512
541
|
[format]
|
513
542
|
end
|
@@ -523,7 +552,7 @@ module HotGlue
|
|
523
552
|
if @namespace
|
524
553
|
begin
|
525
554
|
eval(controller_descends_from)
|
526
|
-
puts " skipping base controller #{controller_descends_from}"
|
555
|
+
# puts " skipping base controller #{controller_descends_from}"
|
527
556
|
rescue NameError => e
|
528
557
|
template "base_controller.rb.erb", File.join("#{'spec/dummy/' if Rails.env.test?}app/controllers#{namespace_with_dash}", "base_controller.rb")
|
529
558
|
end
|
@@ -590,34 +619,32 @@ module HotGlue
|
|
590
619
|
end
|
591
620
|
|
592
621
|
def object_parent_mapping_as_argument_for_specs
|
593
|
-
if @
|
594
|
-
", " + @
|
622
|
+
if @nested_set.any?
|
623
|
+
", " + @nested_set.last[:singular] + ": " + @nested_set.last[:singular]
|
595
624
|
elsif @auth
|
596
625
|
", #{@auth_identifier}: #{@auth}"
|
597
626
|
end
|
598
627
|
end
|
599
628
|
|
600
629
|
def objest_nest_factory_setup
|
601
|
-
res = ""
|
630
|
+
res = " "
|
602
631
|
if @auth
|
603
632
|
last_parent = ", #{@auth_identifier}: #{@auth}"
|
604
633
|
end
|
605
634
|
|
606
|
-
@
|
607
|
-
res << " let(:#{arg}) {create(:#{arg} #{last_parent} )}\n"
|
608
|
-
last_parent = ", #{arg}: #{arg}"
|
635
|
+
@nested_set.each do |arg|
|
636
|
+
res << " let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
|
637
|
+
last_parent = ", #{arg[:singular]}: #{arg[:singular]}"
|
609
638
|
end
|
610
639
|
res
|
611
640
|
end
|
612
641
|
|
613
|
-
|
614
642
|
def objest_nest_params_by_id_for_specs
|
615
|
-
@
|
616
|
-
"#{arg}_id: #{arg}.id"
|
643
|
+
@nested_set.map{|arg|
|
644
|
+
"#{arg[:singular]}_id: #{arg[:singular]}.id"
|
617
645
|
}.join(",\n ")
|
618
646
|
end
|
619
647
|
|
620
|
-
|
621
648
|
def controller_class_name
|
622
649
|
@controller_build_name
|
623
650
|
end
|
@@ -626,6 +653,10 @@ module HotGlue
|
|
626
653
|
@singular
|
627
654
|
end
|
628
655
|
|
656
|
+
def testing_name
|
657
|
+
singular_class_name.gsub("::","_").downcase
|
658
|
+
end
|
659
|
+
|
629
660
|
def singular_class_name
|
630
661
|
@singular_class
|
631
662
|
end
|
@@ -638,9 +669,62 @@ module HotGlue
|
|
638
669
|
@auth_identifier
|
639
670
|
end
|
640
671
|
|
672
|
+
def test_capybara_block
|
673
|
+
(@columns - @show_only).map { |col|
|
674
|
+
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
675
|
+
case type
|
676
|
+
when :date
|
677
|
+
" " + "new_#{col} = Date.current + (rand(100).days) \n" +
|
678
|
+
' ' + "find(\"[name='#{testing_name}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
679
|
+
when :time
|
680
|
+
# " " + "new_#{col} = DateTime.current + (rand(100).days) \n" +
|
681
|
+
# ' ' + "find(\"[name='#{singular}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
682
|
+
|
683
|
+
when :datetime
|
684
|
+
" " + "new_#{col} = DateTime.current + (rand(100).days) \n" +
|
685
|
+
' ' + "find(\"[name='#{testing_name}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
686
|
+
|
687
|
+
when :integer
|
688
|
+
|
689
|
+
if col.to_s.ends_with?("_id")
|
690
|
+
assoc = col.to_s.gsub('_id','')
|
691
|
+
" #{col}_selector = find(\"[name='#{singular}[#{col}]']\").click \n" +
|
692
|
+
" #{col}_selector.first('option', text: #{assoc}1.name).select_option"
|
693
|
+
else
|
694
|
+
" new_#{col} = rand(10) \n" +
|
695
|
+
" find(\"[name='#{testing_name}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
696
|
+
|
697
|
+
end
|
698
|
+
|
699
|
+
when :enum
|
700
|
+
" list_of_#{col.to_s} = #{singular_class}.defined_enums['#{col.to_s}'].keys \n" +
|
701
|
+
" " + "new_#{col.to_s} = list_of_#{col.to_s}[rand(list_of_#{col.to_s}.length)].to_s \n" +
|
702
|
+
' find("select[name=\'' + singular + '[' + col.to_s + ']\'] option[value=\'#{new_' + col.to_s + '}\']").select_option'
|
703
|
+
|
704
|
+
when :boolean
|
705
|
+
" new_#{col} = rand(2).floor \n" +
|
706
|
+
" find(\"[name='#{testing_name}[#{col}]'][value='\#{new_" + col.to_s + "}']\").choose"
|
707
|
+
when :string
|
708
|
+
if col.to_s.include?("email")
|
709
|
+
" " + "new_#{col} = 'new_test-email@nowhere.com' \n" +
|
710
|
+
" find(\"[name='#{testing_name}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
711
|
+
|
712
|
+
else
|
713
|
+
" " + "new_#{col} = 'new_test-email@nowhere.com' \n" +
|
714
|
+
" find(\"[name='#{testing_name}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
715
|
+
end
|
716
|
+
when :text
|
717
|
+
" " + "new_#{col} = FFaker::Lorem.paragraphs(1).join("") \n" +
|
718
|
+
" find(\"[name='#{testing_name}[#{ col.to_s }]']\").fill_in(with: new_#{col.to_s})"
|
719
|
+
end
|
720
|
+
|
721
|
+
}.join("\n")
|
722
|
+
end
|
723
|
+
|
724
|
+
|
641
725
|
def path_helper_args
|
642
|
-
if @
|
643
|
-
[(@
|
726
|
+
if @nested_set.any? && @nested
|
727
|
+
[(@nested_set).collect{|a| "#{a[:singular]}"} , singular].join(",")
|
644
728
|
else
|
645
729
|
singular
|
646
730
|
end
|
@@ -648,7 +732,7 @@ module HotGlue
|
|
648
732
|
|
649
733
|
def path_helper_singular
|
650
734
|
if @nested
|
651
|
-
"#{@namespace+"_" if @namespace}#{(@
|
735
|
+
"#{@namespace+"_" if @namespace}#{(@nested_set.collect{|x| x[:singular]}.join("_") + "_" if @nested_set.any?)}#{@controller_build_folder_singular}_path"
|
652
736
|
else
|
653
737
|
"#{@namespace+"_" if @namespace}#{@controller_build_folder_singular}_path"
|
654
738
|
end
|
@@ -697,7 +781,7 @@ module HotGlue
|
|
697
781
|
|
698
782
|
def path_arity
|
699
783
|
res = ""
|
700
|
-
if @
|
784
|
+
if @nested_set.any? && @nested
|
701
785
|
res << nested_objects_arity + ", "
|
702
786
|
end
|
703
787
|
res << "@" + singular
|
@@ -716,33 +800,24 @@ module HotGlue
|
|
716
800
|
end
|
717
801
|
|
718
802
|
def new_path_name
|
719
|
-
|
720
803
|
HotGlue.optionalized_ternary(namespace: @namespace,
|
721
804
|
target: singular,
|
722
805
|
nested_set: @nested_set,
|
723
806
|
modifier: "new_",
|
724
807
|
with_params: true)
|
725
|
-
# base = "new_#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_") if @nested_args.any?}#{@controller_build_folder_singular}_path"
|
726
|
-
# if @nested_args.any?
|
727
|
-
# base += "(" + @nested_args.collect { |arg|
|
728
|
-
# "#{arg}.id"
|
729
|
-
# }.join(", ") + ")"
|
730
|
-
# end
|
731
|
-
# base
|
732
808
|
end
|
733
809
|
|
734
810
|
def nested_assignments
|
735
|
-
return "" if @
|
736
|
-
@
|
811
|
+
return "" if @nested_set.none?
|
812
|
+
@nested_set.map{|a| "#{a}: #{a}"}.join(", ") #metaprgramming into Ruby hash
|
737
813
|
end
|
738
814
|
|
739
815
|
def nested_assignments_top_level # this is by accessing the instance variable-- only use at top level
|
740
|
-
@
|
816
|
+
@nested_set.map{|a| "#{a[:singular]}"}.join(", ") #metaprgramming into Ruby hash
|
741
817
|
end
|
742
818
|
|
743
|
-
|
744
819
|
def nest_assignments_operator(top_level = false, leading_comma = false)
|
745
|
-
if @
|
820
|
+
if @nested_set.any?
|
746
821
|
"#{", " if leading_comma}#{top_level ? nested_assignments_top_level : nested_assignments }"
|
747
822
|
else
|
748
823
|
""
|
@@ -754,25 +829,25 @@ module HotGlue
|
|
754
829
|
end
|
755
830
|
|
756
831
|
def nested_objects_arity
|
757
|
-
@
|
832
|
+
@nested_set.map{|a| "@#{a[:singular]}"}.join(", ")
|
758
833
|
end
|
759
834
|
|
760
835
|
def nested_arity_for_path
|
761
|
-
[@
|
836
|
+
[@nested_set[0..-1].collect{|a| "@#{a[:singular]}"}].join(", ") #metaprgramming into arity for the Rails path helper
|
762
837
|
end
|
763
838
|
|
764
839
|
def object_scope
|
765
840
|
if @auth
|
766
|
-
if @
|
841
|
+
if @nested_set.none?
|
767
842
|
@auth + ".#{plural}"
|
768
843
|
else
|
769
|
-
"@" + @
|
844
|
+
"@" + @nested_set.last[:singular] + ".#{plural}"
|
770
845
|
end
|
771
846
|
else
|
772
|
-
if @
|
847
|
+
if @nested_set.none?
|
773
848
|
@singular_class
|
774
849
|
else
|
775
|
-
"@" + @
|
850
|
+
"@" + @nested_set.last[:singular] + ".#{plural}"
|
776
851
|
end
|
777
852
|
|
778
853
|
end
|
@@ -783,10 +858,10 @@ module HotGlue
|
|
783
858
|
if @auth
|
784
859
|
if @self_auth
|
785
860
|
@singular_class + ".where(id: #{@auth}.id)"
|
786
|
-
elsif @
|
861
|
+
elsif @nested_set.none?
|
787
862
|
@auth + ".#{plural}"
|
788
863
|
else
|
789
|
-
"@" + @
|
864
|
+
"@" + @nested_set.last[:singular] + ".#{plural}"
|
790
865
|
end
|
791
866
|
else
|
792
867
|
@singular_class + ".all"
|
@@ -794,7 +869,7 @@ module HotGlue
|
|
794
869
|
end
|
795
870
|
|
796
871
|
def any_nested?
|
797
|
-
@
|
872
|
+
@nested_set.any?
|
798
873
|
end
|
799
874
|
|
800
875
|
def all_objects_variable
|
@@ -859,7 +934,7 @@ module HotGlue
|
|
859
934
|
#
|
860
935
|
# if File.exists?(menu_file)
|
861
936
|
# # TODO: can I insert the new menu item into the menu programatically here?
|
862
|
-
# # not sure how i would
|
937
|
+
# # not sure how i would achieve this without nokogiri
|
863
938
|
#
|
864
939
|
# end
|
865
940
|
|
@@ -935,6 +1010,7 @@ module HotGlue
|
|
935
1010
|
show_only: @show_only,
|
936
1011
|
singular_class: singular_class,
|
937
1012
|
singular: singular,
|
1013
|
+
hawk_keys: @hawk_keys,
|
938
1014
|
col_identifier: col_identifier,
|
939
1015
|
ownership_field: @ownership_field,
|
940
1016
|
form_labels_position: @form_labels_position,
|
@@ -1024,9 +1100,8 @@ module HotGlue
|
|
1024
1100
|
"display_name"
|
1025
1101
|
elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
|
1026
1102
|
"email"
|
1027
|
-
elsif me.column_names.include?("number") || me.instance_methods(false).include?(:number)
|
1028
|
-
"number"
|
1029
1103
|
else
|
1104
|
+
# NOT UNREACHABLE BUT UNTESTED
|
1030
1105
|
exit_message = "*** Oops: Can't find any column to use as the display label on #{singular_class} model . TODO: Please implement just one of: 1) name, 2) to_label, 3) full_name, 4) display_name, 5) email, or 6) number directly on your #{singular_class} model (either as database field or model methods), then RERUN THIS GENERATOR. (If more than one is implemented, the field to use will be chosen based on the rank here, e.g., if name is present it will be used; if not, I will look for a to_label, etc)"
|
1031
1106
|
raise(HotGlue::Error, exit_message)
|
1032
1107
|
end
|
@@ -1106,7 +1181,7 @@ module HotGlue
|
|
1106
1181
|
def nested_for_turbo_nested_constructor(top_level = true)
|
1107
1182
|
instance_symbol = "@" if top_level
|
1108
1183
|
instance_symbol = "" if !top_level
|
1109
|
-
if @
|
1184
|
+
if @nested_set.none?
|
1110
1185
|
"\"\""
|
1111
1186
|
else
|
1112
1187
|
@nested_set.collect{|arg|
|
@@ -1118,10 +1193,10 @@ module HotGlue
|
|
1118
1193
|
def nested_for_assignments_constructor(top_level = true)
|
1119
1194
|
instance_symbol = "@" if top_level
|
1120
1195
|
instance_symbol = "" if !top_level
|
1121
|
-
if @
|
1196
|
+
if @nested_set.none?
|
1122
1197
|
""
|
1123
1198
|
else
|
1124
|
-
", \n nested_for: \"" + @
|
1199
|
+
", \n nested_for: \"" + @nested_set.collect{|a| "#{a[:singular]}-" + '#{' + instance_symbol + a[:singular] + ".id}"}.join("__") + "\""
|
1125
1200
|
end
|
1126
1201
|
end
|
1127
1202
|
|
@@ -1130,6 +1205,12 @@ module HotGlue
|
|
1130
1205
|
def cc_filename_with_extensions(name, file_format = format)
|
1131
1206
|
[name, file_format].compact.join(".")
|
1132
1207
|
end
|
1208
|
+
|
1209
|
+
def hawk_to_ruby
|
1210
|
+
@hawk_keys.collect{ |k,v|
|
1211
|
+
"#{k}: [#{v[0]}, \"#{v[1]}\"] "
|
1212
|
+
}.join(", ")
|
1213
|
+
end
|
1133
1214
|
end
|
1134
1215
|
end
|
1135
1216
|
|