hot-glue 0.5.8 → 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
 
440
- @menu_file_exists = true if @nested_set.none? && File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
441
479
 
442
- @turbo_streams = !!options['with_turbo_streams']
443
480
 
481
+ @menu_file_exists = true if @nested_set.none? && File.exist?("#{Rails.root}/app/views/#{namespace_with_trailing_dash}_menu.#{@markup}")
444
482
 
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`)
483
+ @turbo_streams = !!options['with_turbo_streams']
448
484
 
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
485
 
456
- data = {lookup_as: lookup_as.gsub("+",""),
457
- assoc: assoc,
458
- with_create: lookup_as.include?("+")}
459
- @alt_lookups[key] = data
460
- end
461
486
 
462
- puts "------ ALT LOOKUPS for #{@alt_lookups}"
463
487
 
464
- @update_alt_lookups = @alt_lookups.collect{|key, value|
465
- @update_show_only.include?(key) ?
466
- { key: value }
467
- : nil}.compact
468
488
 
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
489
 
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
 
@@ -509,24 +525,115 @@ module HotGlue
509
525
  end
510
526
 
511
527
  hawk_scope = key.gsub("_id", "").pluralize
512
- @hawk_keys[key.to_sym] = [hawk_to]
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}
513
531
  use_shorthand = !options["hawk"].include?("{")
514
532
 
515
533
  if use_shorthand # only include the hawk scope if using the shorthand
516
- @hawk_keys[key.to_sym] << hawk_scope
534
+ @hawk_keys[key.to_sym][:bind_to] << hawk_scope
517
535
  end
536
+
518
537
  end
519
538
 
520
539
  puts "HAWKING: #{@hawk_keys}"
521
540
  end
522
541
  end
523
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
+
524
630
  def identify_object_owner
525
631
  auth_assoc = @auth && @auth.gsub("current_","")
526
632
 
527
633
  if @object_owner_sym && ! @self_auth
528
634
  auth_assoc_field = auth_assoc + "_id" unless @god
529
635
  assoc = eval("#{singular_class}.reflect_on_association(:#{@object_owner_sym})")
636
+
530
637
  if assoc
531
638
  @ownership_field = assoc.name.to_s + "_id"
532
639
  elsif ! @nested_set.any?
@@ -561,54 +668,70 @@ module HotGlue
561
668
 
562
669
  @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| @exclude_fields.include?(field) }
563
670
 
671
+
564
672
  else
565
673
  @columns = @the_object.columns.map(&:name).map(&:to_sym).reject{|field| !@include_fields.include?(field) }
566
674
  end
567
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
+
568
684
 
569
685
  @associations = []
686
+
570
687
  @columns.each do |col|
571
688
  if col.to_s.starts_with?("_")
572
689
  @show_only << col
573
690
  end
574
691
 
575
- if @the_object.columns_hash[col.to_s].type == :integer
576
- if col.to_s.ends_with?("_id")
577
- # guess the association name label
578
- assoc_name = col.to_s.gsub("_id","")
579
-
580
-
581
- assoc_model = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
582
-
583
- if assoc_model.nil?
584
- 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."
585
- puts exit_message
586
- raise(HotGlue::Error, exit_message)
587
- end
588
-
589
- begin
590
- assoc_class = eval(assoc_model.try(:class_name))
591
- @associations << assoc_name.to_sym
592
- name_list = [:name, :to_label, :full_name, :display_name, :email]
593
-
594
- rescue
595
- # unreachable(?)
596
- # if eval("#{singular_class}.reflect_on_association(:#{assoc_name.singularize})")
597
- # raise(HotGlue::Error,"*** Oops: #{singular_class} has no association for #{assoc_name.singularize}")
598
- # else
599
- # 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.")
600
- # end
601
- end
602
-
603
- if assoc_class && name_list.collect{ |field|
604
- assoc_class.column_names.include?(field.to_s) || assoc_class.instance_methods.include?(field)
605
- }.any?
606
- # do nothing here
607
- else
608
- 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.)"
609
- 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
610
729
  end
611
730
  end
731
+ elsif @attachments.keys.include?(col)
732
+
733
+ else
734
+ raise "couldn't find #{col} in either field list or attachments list"
612
735
  end
613
736
  end
614
737
  end
@@ -671,7 +794,7 @@ module HotGlue
671
794
  end
672
795
 
673
796
  def spec_related_column_lets
674
- (@columns - @show_only).map { |col|
797
+ (@columns - @show_only - @attachments.keys).map { |col|
675
798
  type = eval("#{singular_class}.columns_hash['#{col}']").type
676
799
  if (type == :integer && col.to_s.ends_with?("_id") || type == :uuid)
677
800
  assoc = "#{col.to_s.gsub('_id','')}"
@@ -685,7 +808,7 @@ module HotGlue
685
808
 
686
809
  def list_column_headings
687
810
  @template_builder.list_column_headings(
688
- columns: @layout_object[:columns][:container],
811
+ layout_object: @layout_object,
689
812
  col_identifier: @layout_strategy.column_classes_for_column_headings,
690
813
  column_width: @layout_strategy.column_width,
691
814
  singular: @singular
@@ -693,7 +816,7 @@ module HotGlue
693
816
  end
694
817
 
695
818
  def columns_spec_with_sample_data
696
- @columns.map { |c|
819
+ (@columns - @attachments.keys).map { |c|
697
820
  type = eval("#{singular_class}.columns_hash['#{c}']").type
698
821
  random_data = case type
699
822
  when :integer
@@ -715,23 +838,25 @@ module HotGlue
715
838
  end
716
839
 
717
840
  def object_parent_mapping_as_argument_for_specs
841
+
718
842
  if @self_auth
719
843
  ""
720
- elsif @nested_set.any?
844
+ elsif @nested_set.any? && ! @nested_set.last[:optional]
721
845
  ", " + @nested_set.last[:singular] + ": " + @nested_set.last[:singular]
722
- elsif @auth
846
+ elsif @auth && !@god
723
847
  ", #{@auth_identifier}: #{@auth}"
724
848
  end
725
849
  end
726
850
 
727
851
  def objest_nest_factory_setup
728
- res = " "
852
+ # TODO: figure out what this is for
853
+ res = ""
729
854
  if @auth
730
855
  last_parent = ", #{@auth_identifier}: #{@auth}"
731
856
  end
732
857
 
733
858
  @nested_set.each do |arg|
734
- res << "let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
859
+ res << " let(:#{arg[:singular]}) {create(:#{arg[:singular]} #{last_parent} )}\n"
735
860
  last_parent = ", #{arg[:singular]}: #{arg[:singular]}"
736
861
  end
737
862
  res
@@ -768,7 +893,7 @@ module HotGlue
768
893
  end
769
894
 
770
895
  def test_capybara_block(which_partial = :create)
771
- (@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|
772
897
  type = eval("#{singular_class}.columns_hash['#{col}']").type
773
898
  case type
774
899
  when :date
@@ -1154,19 +1279,8 @@ module HotGlue
1154
1279
  end
1155
1280
 
1156
1281
  def form_fields_html
1157
- @template_builder.all_form_fields(
1158
- columns: @layout_object[:columns][:container],
1159
- show_only: @show_only,
1160
- update_show_only: @update_show_only,
1161
- singular_class: singular_class,
1162
- singular: singular,
1163
- hawk_keys: @hawk_keys,
1164
- col_identifier: @layout_strategy.column_classes_for_form_fields,
1165
- ownership_field: @ownership_field,
1166
- form_labels_position: @form_labels_position,
1167
- form_placeholder_labels: @form_placeholder_labels,
1168
- alt_lookups: @alt_lookups
1169
- )
1282
+ @template_builder.all_form_fields(layout_strategy: @layout_strategy,
1283
+ layout_object: @layout_object)
1170
1284
  end
1171
1285
 
1172
1286
  def list_label
@@ -1179,13 +1293,15 @@ module HotGlue
1179
1293
 
1180
1294
  def all_line_fields
1181
1295
  @template_builder.all_line_fields(
1182
- perc_width: @layout_strategy.each_col, #undefined method `each_col'
1183
- columns: @layout_object[:columns][:container],
1184
- show_only: @show_only,
1185
- singular_class: singular_class,
1186
- singular: singular,
1187
1296
  col_identifier: @layout_strategy.column_classes_for_line_fields,
1188
- 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
1189
1305
  )
1190
1306
  end
1191
1307
 
@@ -1216,7 +1332,6 @@ module HotGlue
1216
1332
  elsif me.column_names.include?("email") || me.instance_methods(false).include?(:email)
1217
1333
  "email"
1218
1334
  else
1219
- # NOT UNREACHABLE BUT UNTESTED
1220
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)"
1221
1336
  raise(HotGlue::Error, exit_message)
1222
1337
  end
@@ -1282,8 +1397,8 @@ module HotGlue
1282
1397
  end
1283
1398
 
1284
1399
  def n_plus_one_includes
1285
- if @associations.any?
1286
- ".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(", ") + ")"
1287
1402
  else
1288
1403
  ""
1289
1404
  end
@@ -1319,9 +1434,17 @@ module HotGlue
1319
1434
 
1320
1435
  def hawk_to_ruby
1321
1436
  res = @hawk_keys.collect{ |k,v|
1322
- "#{k}: [#{v[0]}, \"#{v[1]}\"]"
1437
+ "#{k.to_s}: [#{v[:bind_to].join(".")}]"
1323
1438
  }.join(", ")
1324
1439
  res
1325
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
1326
1449
  end
1327
1450
  end
@@ -41,20 +41,25 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
41
41
  <% else %>
42
42
  @<%= @nested_set[0][:singular] %> ||= <%= root_object %>.find(params[:<%= @nested_set[0][:singular] %>_id])<%= " if params.include?(:#{@nested_set[0][:singular]}_id)" if @nested_set[0][:optional] %> <% end %>
43
43
  end
44
- <% end %><% if any_nested? %><% nest_chain = [@nested_set[0][:singular]]; this_scope = @nested_set[0][:plural]; %>
45
- <% for index in 0..(@nested_set.count - 1) do
44
+ <% end %><% if any_nested? %><% nest_chain = [@nested_set[0][:singular]]; %>
45
+ <% for index in 1..(@nested_set.count - 1) do
46
46
  arg = @nested_set[index]
47
+
47
48
  last_arg = (index == 0 ? nil : @nested_set[index-1])
48
49
 
49
50
  this_scope = "#{nest_chain.last}.#{arg[:plural]}"
50
- nest_chain << arg %>
51
- <% unless @nested_set[0][:singular] == arg[:singular] %>
51
+ nest_chain << arg[:singular] %>
52
52
  def <%= arg[:singular] %>
53
- @<%= arg[:singular] %> ||= (<%= this_scope %>.find(params[:<%= arg[:singular] %>_id])<%= " if params.include?(:#{last_arg[:singular]}_id)" if last_arg && @god && last_arg[:optional] %>)
53
+ @<%= arg[:singular] %> ||= (<%= this_scope; %>.find(params[:<%= arg[:singular] %>_id]) <%= " if params.include?(:#{last_arg[:singular]}_id)" if last_arg && @god && last_arg[:optional] %>)
54
54
  <% if @god && last_arg && (last_arg[:optional] ) %>@<%= arg[:singular] %> ||= (<%= collect_objects[index-1] %>.find(params[:<%= arg[:singular] %>_id]) if params.include?(:<%= arg[:singular] %>_id) ) <% end %>
55
- end<% end %><% end %><% end %> <% if !@self_auth %>
55
+ end<% end %><% end %>
56
+ <% if !@self_auth %>
56
57
  def load_<%= singular_name %>
57
- @<%= singular_name %> = <%= object_scope.gsub("@",'') %>.find(params[:id])<%= " if params.include?(:#{@nested_set.last[:singular]}_id)" if @nested_set[0] && @nested_set[0][:optional] %><% if @nested_set[0] && @nested_set[0][:optional] %> || <%= class_name %>.find(params[:id])<% end %>
58
+ <% if @nested_set[0] && @nested_set[0][:optional] %>if params.include?(:<%= @nested_set.last[:singular] %>_id)
59
+ @<%= singular_name %> = <%= object_scope.gsub("@",'') %>.find(params[:id])
60
+ else
61
+ <% end %>@<%= singular_name %> = <%= object_scope %>.find(params[:id])<% if @nested_set[0] && @nested_set[0][:optional] %>
62
+ end<% end %>
58
63
  end
59
64
  <% else %>
60
65
  def load_<%= singular_name %>
@@ -83,8 +88,9 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
83
88
  " #{data[:assoc].downcase} = #{data[:assoc]}.#{data[:with_create] ? "find_or_create_by" : "find_by"}(#{data[:lookup_as]}: #{ singular_name }_params[:__lookup_#{data[:lookup_as]}])\n"
84
89
  }.join("/n") %><% end %> <% merge_lookups = @alt_lookups.collect{|key, data| "#{key.gsub("_id", "")}: #{key.gsub("_id", "")}" }.join(",") %>
85
90
  modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<%= controller_update_params_tap_away_alt_lookups %><% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>.merge!(<% if @object_owner_optional && any_nested? %><%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}<% else %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)<% end %>)<%= ".merge(#{merge_lookups})" if !merge_lookups.empty? %><% if @hawk_keys.any? %>
86
- modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
91
+ modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %><%= controller_attachment_orig_filename_pickup_syntax %>
87
92
  <%= creation_syntax %>
93
+
88
94
  if @<%= singular_name %>.save
89
95
  flash[:notice] = "Successfully created #{@<%= singular %>.<%= display_class %>}"
90
96
  load_all_<%= plural %>
@@ -116,7 +122,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
116
122
  }.join("/n") %><% end %><% if (@update_alt_lookups).any? %>
117
123
  <%= @update_alt_lookups.collect{|key, data|
118
124
  " @#{ singular_name }.#{key.gsub("_id", "")} = #{key.gsub("_id", "")}"
119
- }.join("/n") %><% end %>
125
+ }.join("/n") %><% end %><%= controller_attachment_orig_filename_pickup_syntax %>
120
126
  if @<%= singular_name %>.update(modified_params)
121
127
  <% if @display_list_after_update %> load_all_<%= plural %><% end %>
122
128
  flash[:notice] = (flash[:notice] || "") << "Saved #{@<%= singular %>.<%= display_class %>}"