hot-glue 0.5.7 → 0.5.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -70,7 +70,7 @@ module HotGlue
70
70
  with_params: with_params,
71
71
  put_form: put_form,
72
72
  nested_set: rest_of_nest )
73
- return "defined?(#{instance_sym + nested_set[0][:singular]}) ? #{is_present_path} : #{is_missing_path}"
73
+ return "defined?(#{instance_sym + nested_set[0][:singular]}2) ? #{is_present_path} : #{is_missing_path}"
74
74
  end
75
75
  end
76
76
 
@@ -150,8 +150,8 @@ module HotGlue
150
150
  class_option :inline_list_labels, default: 'omit' # choices are before, after, omit
151
151
  class_option :factory_creation, default: ''
152
152
  class_option :alt_foreign_key_lookup, default: '' #
153
-
154
-
153
+ class_option :attachments, default: ''
154
+ class_option :stacked_downnesting, default: false
155
155
 
156
156
  def initialize(*meta_args)
157
157
  super
@@ -215,15 +215,6 @@ module HotGlue
215
215
  LayoutStrategy::HotGlue.new(self)
216
216
  end
217
217
 
218
-
219
- if @markup == "erb"
220
- @template_builder = HotGlue::ErbTemplate.new(layout_strategy: @layout_strategy)
221
- elsif @markup == "slim"
222
- raise(HotGlue::Error, "SLIM IS NOT IMPLEMENTED")
223
- elsif @markup == "haml"
224
- raise(HotGlue::Error, "HAML IS NOT IMPLEMENTED")
225
- end
226
-
227
218
  args = meta_args[0]
228
219
  @singular = args.first.tableize.singularize # should be in form hello_world
229
220
 
@@ -233,32 +224,21 @@ module HotGlue
233
224
 
234
225
  @plural = options['plural'] || @singular.pluralize # respects what you set in inflections.rb, to override, use plural option
235
226
  @namespace = options['namespace'] || nil
236
-
237
-
238
227
  use_controller_name = plural.titleize.gsub(" ", "")
239
-
240
228
  @controller_build_name = (( @namespace.titleize.gsub(" ","") + "::" if @namespace) || "") + use_controller_name + "Controller"
241
229
  @controller_build_folder = use_controller_name.underscore
242
230
  @controller_build_folder_singular = singular
243
231
 
244
- # if ! @controller_build_folder.ends_with?("s")
245
- # raise HotGlue::Error, "can't build with controller name #{@controller_build_folder} because it doesn't end with an 's'"
246
- # end
247
-
248
232
  @auth = options['auth'] || "current_user"
249
233
  @auth_identifier = options['auth_identifier'] || (! @god && @auth.gsub("current_", "")) || nil
250
234
 
251
-
252
-
253
235
  if options['nest']
254
236
  raise HotGlue::Error, "STOP: the flag --nest has been replaced with --nested; please re-run using the --nested flag"
255
-
256
237
  end
257
-
258
238
  @nested = (!options['nested'].empty? && options['nested']) || nil
259
-
260
239
  @singular_class = args.first # note this is the full class name with a model namespace
261
240
 
241
+ setup_attachments
262
242
 
263
243
  @exclude_fields = []
264
244
  @exclude_fields += options['exclude'].split(",").collect(&:to_sym)
@@ -270,7 +250,6 @@ module HotGlue
270
250
  @include_fields += options['include'].split(":").collect{|x|x.split(",")}.flatten.collect(&:to_sym)
271
251
  end
272
252
 
273
-
274
253
  @show_only = []
275
254
  if !options['show_only'].empty?
276
255
  @show_only += options['show_only'].split(",").collect(&:to_sym)
@@ -282,6 +261,76 @@ module HotGlue
282
261
  end
283
262
 
284
263
 
264
+ # syntax should be xyz_id{xyz_email},abc_id{abc_email}
265
+ # instead of a drop-down for the foreign entity, a text field will be presented
266
+ # You must ALSO use a factory that contains a parameter of the same name as the 'value' (for example, `xyz_email`)
267
+
268
+ alt_lookups_entry = options['alt_foreign_key_lookup'].split(",")
269
+ @alt_lookups = {}
270
+ @alt_foreign_key_lookup = alt_lookups_entry.each do |setting|
271
+ setting =~ /(.*){(.*)}/
272
+ key, lookup_as = $1, $2
273
+ assoc = eval("#{class_name}.reflect_on_association(:#{key.to_s.gsub("_id","")}).class_name")
274
+
275
+ data = {lookup_as: lookup_as.gsub("+",""),
276
+ assoc: assoc,
277
+ with_create: lookup_as.include?("+")}
278
+ @alt_lookups[key] = data
279
+ end
280
+
281
+ puts "------ ALT LOOKUPS for #{@alt_lookups}"
282
+
283
+ @update_alt_lookups = @alt_lookups.collect{|key, value|
284
+ @update_show_only.include?(key) ?
285
+ { key: value }
286
+ : nil}.compact
287
+
288
+ @label = options['label'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_singular)") ? eval("#{class_name}.class_variable_get(:@@table_label_singular)") : singular.gsub("_", " ").titleize )
289
+ @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 )
290
+
291
+ @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 )
292
+ @new_form_heading = options['new_form_heading'] || "New #{@label}"
293
+
294
+
295
+
296
+ setup_hawk_keys
297
+ @form_placeholder_labels = options['form_placeholder_labels'] # true or false
298
+ @inline_list_labels = options['inline_list_labels'] || 'omit' # 'before','after','omit'
299
+
300
+
301
+ @form_labels_position = options['form_labels_position']
302
+ if !['before','after','omit'].include?(@form_labels_position)
303
+ 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"
304
+ end
305
+
306
+ if !['before','after','omit'].include?(@inline_list_labels)
307
+ 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)"
308
+ end
309
+
310
+
311
+
312
+ if @markup == "erb"
313
+ @template_builder = HotGlue::ErbTemplate.new(
314
+ layout_strategy: @layout_strategy,
315
+ magic_buttons: @magic_buttons,
316
+ small_buttons: @small_buttons,
317
+ inline_list_labels: @inline_list_labels,
318
+ show_only: @show_only,
319
+ update_show_only: @update_show_only,
320
+ singular_class: singular_class,
321
+ singular: singular,
322
+ hawk_keys: @hawk_keys,
323
+ ownership_field: @ownership_field,
324
+ form_labels_position: @form_labels_position,
325
+ form_placeholder_labels: @form_placeholder_labels,
326
+ alt_lookups: @alt_lookups,
327
+ attachments: @attachments,
328
+ )
329
+ elsif @markup == "slim"
330
+ raise(HotGlue::Error, "SLIM IS NOT IMPLEMENTED")
331
+ elsif @markup == "haml"
332
+ raise(HotGlue::Error, "HAML IS NOT IMPLEMENTED")
333
+ end
285
334
 
286
335
  @god = options['god'] || options['gd'] || false
287
336
  @specs_only = options['specs_only'] || false
@@ -297,20 +346,8 @@ module HotGlue
297
346
  @no_list = options['no_list'] || false
298
347
  @no_list_label = options['no_list_label'] || false
299
348
  @no_list_heading = options['no_list_heading'] || false
349
+ @stacked_downnesting = options['stacked_downnesting']
300
350
 
301
- @form_labels_position = options['form_labels_position']
302
- if !['before','after','omit'].include?(@form_labels_position)
303
-
304
- 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"
305
- end
306
-
307
- @form_placeholder_labels = options['form_placeholder_labels'] # true or false
308
- @inline_list_labels = options['inline_list_labels'] || 'omit' # 'before','after','omit'
309
-
310
-
311
- if !['before','after','omit'].include?(@inline_list_labels)
312
- 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)"
313
- end
314
351
 
315
352
 
316
353
 
@@ -415,15 +452,16 @@ module HotGlue
415
452
  end
416
453
  end
417
454
 
418
- identify_object_owner
419
- setup_hawk_keys
420
455
 
421
456
  @factory_creation = options['factory_creation'].gsub(";", "\n")
422
457
 
458
+ identify_object_owner
459
+
423
460
 
424
461
 
425
462
  # SETUP FIELDS & LAYOUT
426
463
  setup_fields
464
+
427
465
  if (@columns - @show_only - (@ownership_field ? [@ownership_field.to_sym] : [])).empty?
428
466
  @no_field_form = true
429
467
  end
@@ -434,43 +472,21 @@ module HotGlue
434
472
  downnest_object: @downnest_object,
435
473
  buttons_width: buttons_width,
436
474
  columns: @columns,
437
- smart_layout: @smart_layout )
475
+ smart_layout: @smart_layout,
476
+ stacked_downnesting: @stacked_downnesting)
438
477
  @layout_object = builder.construct
439
478
 
479
+
480
+
440
481
  @menu_file_exists = true if @nested_set.none? && File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
441
482
 
442
483
  @turbo_streams = !!options['with_turbo_streams']
443
484
 
444
485
 
445
- # syntax should be xyz_id{xyz_email},abc_id{abc_email}
446
- # instead of a drop-down for the foreign entity, a text field will be presented
447
- # You must ALSO use a factory that contains a parameter of the same name as the 'value' (for example, `xyz_email`)
448
486
 
449
- alt_lookups_entry = options['alt_foreign_key_lookup'].split(",")
450
- @alt_lookups = {}
451
- @alt_foreign_key_lookup = alt_lookups_entry.each do |setting|
452
- setting =~ /(.*){(.*)}/
453
- key, lookup_as = $1, $2
454
- assoc = eval("#{class_name}.reflect_on_association(:#{key.to_s.gsub("_id","")}).class_name")
455
487
 
456
- data = {lookup_as: lookup_as.gsub("+",""),
457
- assoc: assoc,
458
- with_create: lookup_as.include?("+")}
459
- @alt_lookups[key] = data
460
- end
461
488
 
462
- puts "------ ALT LOOKUPS for #{@alt_lookups}"
463
489
 
464
- @update_alt_lookups = @alt_lookups.collect{|key, value|
465
- @update_show_only.include?(key) ?
466
- { key: value }
467
- : nil}.compact
468
-
469
- @label = options['label'] || ( eval("#{class_name}.class_variable_defined?(:@@table_label_singular)") ? eval("#{class_name}.class_variable_get(:@@table_label_singular)") : singular.gsub("_", " ").titleize )
470
- @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 )
471
-
472
- @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 )
473
- @new_form_heading = options['new_form_heading'] || "New #{@label}"
474
490
  end
475
491
 
476
492
 
@@ -480,16 +496,19 @@ module HotGlue
480
496
 
481
497
 
482
498
  def creation_syntax
499
+
500
+ merge_with = @alt_lookups.collect{ |key, data|
501
+ "#{data[:assoc].downcase}: #{data[:assoc].downcase}_factory.#{data[:assoc].downcase}"
502
+ }.join(", ")
503
+
483
504
  if @factory_creation == ''
484
505
  "@#{singular_name } = #{ class_name }.create(modified_params)"
485
506
  else
486
507
  "#{@factory_creation}\n" +
487
- " @#{singular_name } = #{ class_name }.create(modified_params)"
508
+ " @#{singular_name } = #{ class_name }.create(modified_params#{'.merge(' + merge_with + ')' if !merge_with.empty?})"
488
509
  end
489
510
  end
490
-
491
-
492
-
511
+
493
512
  def setup_hawk_keys
494
513
  @hawk_keys = {}
495
514
 
@@ -506,24 +525,115 @@ module HotGlue
506
525
  end
507
526
 
508
527
  hawk_scope = key.gsub("_id", "").pluralize
509
- @hawk_keys[key.to_sym] = [hawk_to]
510
- use_shorthand = !hawk_scope.include?("{")
528
+ optional = eval(singular_class + ".reflect_on_association(:#{key.gsub('_id','')})").options[:optional]
529
+
530
+ @hawk_keys[key.to_sym] = {bind_to: [hawk_to], optional: optional}
531
+ use_shorthand = !options["hawk"].include?("{")
511
532
 
512
533
  if use_shorthand # only include the hawk scope if using the shorthand
513
- @hawk_keys[key.to_sym] << hawk_scope
534
+ @hawk_keys[key.to_sym][:bind_to] << hawk_scope
514
535
  end
536
+
515
537
  end
516
538
 
517
539
  puts "HAWKING: #{@hawk_keys}"
518
540
  end
519
541
  end
520
542
 
543
+
544
+ def setup_attachments
545
+ @attachments = {}
546
+
547
+ if options["attachments"]
548
+
549
+ options['attachments'].split(",").each do |attachment_entry|
550
+ # format is: avatar{thumbnail|field_for_original_filename}
551
+
552
+ if attachment_entry.include?("{")
553
+ num_params = attachment_entry.split("|").count
554
+ if num_params == 1
555
+ attachment_entry =~ /(.*){(.*)}/
556
+ key, thumbnail = $1, $2
557
+ elsif num_params == 2
558
+ attachment_entry =~ /(.*){(.*)\|(.*)}/
559
+ key, thumbnail, field_for_original_filename = $1, $2, $3
560
+ elsif num_params > 2
561
+ if num_params == 3
562
+ attachment_entry =~ /(.*){(.*)\|(.*)\|(.*)}/
563
+ key, thumbnail, field_for_original_filename, direct_upload = $1, $2, $3, $4
564
+ elsif num_params > 3
565
+ attachment_entry =~ /(.*){(.*)\|(.*)\|(.*)\|(.*)}/
566
+ key, thumbnail, field_for_original_filename, direct_upload, dropzone = $1, $2, $3, $4, $5
567
+ end
568
+
569
+ field_for_original_filename = nil if field_for_original_filename == ""
570
+
571
+ if thumbnail == ''
572
+ thumbnail = nil
573
+ end
574
+
575
+ if !direct_upload.nil? && direct_upload != "direct"
576
+ 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"
577
+ end
578
+
579
+ if !dropzone.nil? && dropzone != "dropzone"
580
+ 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"
581
+ end
582
+
583
+ if dropzone && !direct_upload
584
+ raise HotGlue::Error, "dropzone requires direct_upload"
585
+ end
586
+
587
+ if field_for_original_filename && direct_upload
588
+ raise HotGlue::Error, "Unfortunately orig filename extraction doesn't work with direct upload; please set 2nd parameter to empty string to disable"
589
+ end
590
+
591
+ direct_upload = !!direct_upload
592
+ dropzone = !!dropzone
593
+ end
594
+ else
595
+ key = attachment_entry
596
+
597
+ if !(eval("#{singular_class}.reflect_on_attachment(:#{attachment_entry})"))
598
+ raise HotGlue::Error, "Could not find #{attachment_entry} attachment on #{singular_class}"
599
+ end
600
+ if eval("#{singular_class}.reflect_on_attachment(:#{attachment_entry}).variants.include?(:thumb)")
601
+ thumbnail = "thumb"
602
+ else
603
+ thumbnail = nil
604
+ end
605
+
606
+ direct_upload = nil
607
+ field_for_original_filename = nil
608
+ dropzone = nil
609
+ end
610
+
611
+ if thumbnail && !eval("#{singular_class}.reflect_on_attachment(:#{key}).variants.include?(:#{thumbnail})")
612
+ 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:
613
+ has_one_attached :#{key} do |attachable|
614
+ attachable.variant :#{thumbnail}, resize_to_limit: [100, 100]
615
+ end
616
+ "
617
+ end
618
+
619
+
620
+ @attachments[key.to_sym] = {thumbnail: thumbnail,
621
+ field_for_original_filename: field_for_original_filename,
622
+ direct_upload: direct_upload,
623
+ dropzone: dropzone}
624
+ end
625
+
626
+ puts "ATTACHMENTS: #{@attachments}"
627
+ end
628
+ end
629
+
521
630
  def identify_object_owner
522
631
  auth_assoc = @auth && @auth.gsub("current_","")
523
632
 
524
633
  if @object_owner_sym && ! @self_auth
525
634
  auth_assoc_field = auth_assoc + "_id" unless @god
526
635
  assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
636
+
527
637
  if assoc
528
638
  @ownership_field = assoc.name.to_s + "_id"
529
639
  elsif ! @nested_set.any?
@@ -558,54 +668,70 @@ module HotGlue
558
668
 
559
669
  @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
560
670
 
671
+
561
672
  else
562
673
  @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| !@include_fields.include?(field) }
563
674
  end
564
675
 
676
+ if @attachments.any?
677
+ puts "adding attachments-as-columns: #{@attachments}"
678
+ @attachments.keys.each do |attachment|
679
+ @columns << attachment if !@columns.include?(attachment)
680
+ end
681
+ end
682
+
683
+
565
684
 
566
685
  @associations = []
686
+
567
687
  @columns.each do |col|
568
688
  if col.to_s.starts_with?("_")
569
689
  @show_only << col
570
690
  end
571
691
 
572
- if @the_object.columns_hash[col.to_s].type == :integer
573
- if col.to_s.ends_with?("_id")
574
- # guess the association name label
575
- assoc_name = col.to_s.gsub("_id","")
576
-
577
-
578
- assoc_model = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
579
-
580
- if assoc_model.nil?
581
- 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."
582
- puts exit_message
583
- raise(HotGlue::Error, exit_message)
584
- end
585
-
586
- begin
587
- assoc_class = eval(assoc_model.try(:class_name))
588
- @associations << assoc_name.to_sym
589
- name_list = [:name, :to_label, :full_name, :display_name, :email]
590
-
591
- rescue
592
- # unreachable(?)
593
- # if eval("#{singular_class}.reflect_on_association(:#{assoc_name.singularize})")
594
- # raise(HotGlue::Error,"*** Oops: #{singular_class} has no association for #{assoc_name.singularize}")
595
- # else
596
- # 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.")
597
- # end
598
- end
599
-
600
- if assoc_class && name_list.collect{ |field|
601
- assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
602
- }.any?
603
- # do nothing here
604
- else
605
- 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.)"
606
- raise(HotGlue::Error,exit_message)
692
+ if @the_object.columns_hash.keys.include?(col.to_s)
693
+ if @the_object.columns_hash[col.to_s].type == :integer
694
+ if col.to_s.ends_with?("_id")
695
+ # guess the association name label
696
+ assoc_name = col.to_s.gsub("_id","")
697
+
698
+
699
+ assoc_model = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
700
+
701
+ if assoc_model.nil?
702
+ 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."
703
+ puts exit_message
704
+ raise(HotGlue::Error, exit_message)
705
+ end
706
+
707
+ begin
708
+ assoc_class = eval(assoc_model.try(:class_name))
709
+ @associations << assoc_name.to_sym
710
+ name_list = [:name, :to_label, :full_name, :display_name, :email]
711
+
712
+ rescue
713
+ # unreachable(?)
714
+ # if eval("#{singular_class}.reflect_on_association(:#{assoc_name.singularize})")
715
+ # raise(HotGlue::Error,"*** Oops: #{singular_class} has no association for #{assoc_name.singularize}")
716
+ # else
717
+ # 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.")
718
+ # end
719
+ end
720
+
721
+ if assoc_class && name_list.collect{ |field|
722
+ assoc_class.respond_to?(field.to_s) || assoc_class.instance_methods.include?(field)
723
+ }.any?
724
+ # do nothing here
725
+ else
726
+ 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.)"
727
+ raise(HotGlue::Error,exit_message)
728
+ end
607
729
  end
608
730
  end
731
+ elsif @attachments.keys.include?(col)
732
+
733
+ else
734
+ raise "couldn't find #{col} in either field list or attachments list"
609
735
  end
610
736
  end
611
737
  end
@@ -638,7 +764,7 @@ module HotGlue
638
764
  end
639
765
 
640
766
  unless @no_specs
641
- dest_file = File.join("#{'spec/dummy/' if Rails.env.test?}spec/system#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
767
+ dest_file = File.join("#{'spec/dummy/' if Rails.env.test?}spec/features#{namespace_with_dash}", "#{plural}_behavior_spec.rb")
642
768
 
643
769
  if File.exist?(dest_file)
644
770
  existing_file = File.open(dest_file)
@@ -668,7 +794,7 @@ module HotGlue
668
794
  end
669
795
 
670
796
  def spec_related_column_lets
671
- (@columns - @show_only).map { |col|
797
+ (@columns - @show_only - @attachments.keys).map { |col|
672
798
  type = eval("#{singular_class}.columns_hash['#{col}']").type
673
799
  if (type == :integer && col.to_s.ends_with?("_id") || type == :uuid)
674
800
  assoc = "#{col.to_s.gsub('_id','')}"
@@ -682,14 +808,15 @@ module HotGlue
682
808
 
683
809
  def list_column_headings
684
810
  @template_builder.list_column_headings(
685
- columns: @layout_object[:columns][:container],
811
+ layout_object: @layout_object,
686
812
  col_identifier: @layout_strategy.column_classes_for_column_headings,
687
- column_width: @layout_strategy.column_width
813
+ column_width: @layout_strategy.column_width,
814
+ singular: @singular
688
815
  )
689
816
  end
690
817
 
691
818
  def columns_spec_with_sample_data
692
- @columns.map { |c|
819
+ (@columns - @attachments.keys).map { |c|
693
820
  type = eval("#{singular_class}.columns_hash['#{c}']").type
694
821
  random_data = case type
695
822
  when :integer
@@ -711,23 +838,25 @@ module HotGlue
711
838
  end
712
839
 
713
840
  def object_parent_mapping_as_argument_for_specs
841
+
714
842
  if @self_auth
715
843
  ""
716
- elsif @nested_set.any?
844
+ elsif @nested_set.any? && ! @nested_set.last[:optional]
717
845
  ", " + @nested_set.last[:singular] + ": " + @nested_set.last[:singular]
718
- elsif @auth
846
+ elsif @auth && !@god
719
847
  ", #{@auth_identifier}: #{@auth}"
720
848
  end
721
849
  end
722
850
 
723
851
  def objest_nest_factory_setup
724
- res = " "
852
+ # TODO: figure out what this is for
853
+ res = ""
725
854
  if @auth
726
855
  last_parent = ", #{@auth_identifier}: #{@auth}"
727
856
  end
728
857
 
729
858
  @nested_set.each do |arg|
730
- res << "let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
859
+ res << " let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
731
860
  last_parent = ", #{arg[:singular]}: #{arg[:singular]}"
732
861
  end
733
862
  res
@@ -764,7 +893,7 @@ module HotGlue
764
893
  end
765
894
 
766
895
  def test_capybara_block(which_partial = :create)
767
- (@columns - (which_partial == :create ? @show_only : (@update_show_only+@show_only))).map { |col|
896
+ ((@columns - @attachments.keys) - (which_partial == :create ? @show_only : (@update_show_only+@show_only))).map { |col|
768
897
  type = eval("#{singular_class}.columns_hash['#{col}']").type
769
898
  case type
770
899
  when :date
@@ -1150,19 +1279,8 @@ module HotGlue
1150
1279
  end
1151
1280
 
1152
1281
  def form_fields_html
1153
- @template_builder.all_form_fields(
1154
- columns: @layout_object[:columns][:container],
1155
- show_only: @show_only,
1156
- update_show_only: @update_show_only,
1157
- singular_class: singular_class,
1158
- singular: singular,
1159
- hawk_keys: @hawk_keys,
1160
- col_identifier: @layout_strategy.column_classes_for_form_fields,
1161
- ownership_field: @ownership_field,
1162
- form_labels_position: @form_labels_position,
1163
- form_placeholder_labels: @form_placeholder_labels,
1164
- alt_lookups: @alt_lookups
1165
- )
1282
+ @template_builder.all_form_fields(layout_strategy: @layout_strategy,
1283
+ layout_object: @layout_object)
1166
1284
  end
1167
1285
 
1168
1286
  def list_label
@@ -1175,13 +1293,15 @@ module HotGlue
1175
1293
 
1176
1294
  def all_line_fields
1177
1295
  @template_builder.all_line_fields(
1178
- perc_width: @layout_strategy.each_col, #undefined method `each_col'
1179
- columns: @layout_object[:columns][:container],
1180
- show_only: @show_only,
1181
- singular_class: singular_class,
1182
- singular: singular,
1183
1296
  col_identifier: @layout_strategy.column_classes_for_line_fields,
1184
- inline_list_labels: @inline_list_labels
1297
+ perc_width: @layout_strategy.each_col, #undefined method `each_col'
1298
+ layout_strategy: @layout_strategy,
1299
+ layout_object: @layout_object
1300
+ # columns: @layout_object[:columns][:container],
1301
+ # show_only: @show_only,
1302
+ # singular_class: singular_class,
1303
+ # singular: singular,
1304
+ # attachments: @attachments
1185
1305
  )
1186
1306
  end
1187
1307
 
@@ -1212,7 +1332,6 @@ module HotGlue
1212
1332
  elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
1213
1333
  "email"
1214
1334
  else
1215
- # NOT UNREACHABLE BUT UNTESTED
1216
1335
  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)"
1217
1336
  raise(HotGlue::Error, exit_message)
1218
1337
  end
@@ -1259,7 +1378,7 @@ module HotGlue
1259
1378
 
1260
1379
  def controller_update_params_tap_away_magic_buttons
1261
1380
  @magic_buttons.collect{ |magic_button|
1262
- ".tap{ |ary| ary.delete('#{magic_button}') }"
1381
+ ".tap{ |ary| ary.delete('__#{magic_button}') }"
1263
1382
  }.join("")
1264
1383
  end
1265
1384
 
@@ -1278,8 +1397,8 @@ module HotGlue
1278
1397
  end
1279
1398
 
1280
1399
  def n_plus_one_includes
1281
- if @associations.any?
1282
- ".includes(" + @associations.map{|x| ":#{x.to_s}"}.join(", ") + ")"
1400
+ if @associations.any? || @attachments.any?
1401
+ ".includes(" + (@associations.map{|x| x} + @attachments.collect{|k,v| "#{k}_attachment"}).map{|x| ":#{x.to_s}"}.join(", ") + ")"
1283
1402
  else
1284
1403
  ""
1285
1404
  end
@@ -1315,9 +1434,17 @@ module HotGlue
1315
1434
 
1316
1435
  def hawk_to_ruby
1317
1436
  res = @hawk_keys.collect{ |k,v|
1318
- "#{k}: [#{v[0]}, \"#{v[1]}\"]"
1437
+ "#{k.to_s}: [#{v[:bind_to].join(".")}]"
1319
1438
  }.join(", ")
1320
1439
  res
1321
1440
  end
1441
+
1442
+ def controller_attachment_orig_filename_pickup_syntax
1443
+ @attachments.collect{ |key, attachment| "\n" + " modified_params[:#{ attachment[:field_for_original_filename] }] = #{singular_name}_params['#{ key }'].original_filename" if attachment[:field_for_original_filename] }.compact.join("\n")
1444
+ end
1445
+
1446
+ def any_datetime_fields?
1447
+ (@columns - @attachments.keys.collect(&:to_sym)).collect{|col| eval("#{singular_class}.columns_hash['#{col}']").type}.include?(:datetime)
1448
+ end
1322
1449
  end
1323
1450
  end