bullet_train-super_scaffolding 1.0.34 → 1.0.37

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e89abdab9630d8af6498af03edec21ce70c456c1579d5c35bf7e16ed3a0383c3
4
- data.tar.gz: 57f3be888b988cc3d0ff747776cb319ec1bc3399f9e55209d94f132c2ef3d6f1
3
+ metadata.gz: 1ca43f2f490c937c87fcc1493b3e194d56f2e39bccd57e01ba7eda9bbaa230fa
4
+ data.tar.gz: f027670522cf4faf29a93bf237874ccffcee91f88fece103522ec2e0c0e21508
5
5
  SHA512:
6
- metadata.gz: cf98aac64c6ee99b4b9778b8d371a770c26d8a1d89925e8e3144aa5b6eee2180890cff7732e700b78c764ff9871a4dc1543db7b3e69e25cc763eb9a16cb34a98
7
- data.tar.gz: d7d0935c5280a7b482e260fe857fba7b7a1dd99076505978ff7d47505921d61abfb041fed3737295f96fb1ffcddc1d368703acd67e2799e01538ac7798887d65
6
+ metadata.gz: 27dba84c5f1fa859f612c33897b747eb5cdcb850d6774dd1a95846c7f7dcf646630d8e8093e023e3084342cc864f2a58a669605147de16fa02fde8b74fcf2cdc
7
+ data.tar.gz: 647922cfdf4696130bf23c1fe15544792ca257cc358acd98baa1f2932f09521d3457ba429fb3c8ff2e6b3a9a3f9d1e53c754b1b92d0f708ee37d6012da49a10f
@@ -16,6 +16,7 @@ class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingsEndpoint < Api::V1
16
16
  optional :date_field_value, type: Date, allow_blank: true, desc: Api.heading(:date_field_value)
17
17
  optional :date_and_time_field_value, type: DateTime, allow_blank: true, desc: Api.heading(:date_and_time_field_value)
18
18
  optional :email_field_value, type: String, allow_blank: true, desc: Api.heading(:email_field_value)
19
+ optional :file_field_value, type: String, allow_blank: true, desc: Api.heading(:file_field_value)
19
20
  optional :password_field_value, type: String, allow_blank: true, desc: Api.heading(:password_field_value)
20
21
  optional :phone_field_value, type: String, allow_blank: true, desc: Api.heading(:phone_field_value)
21
22
  optional :option_value, type: String, allow_blank: true, desc: Api.heading(:option_value)
@@ -1,5 +1,6 @@
1
1
  class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingSerializer < Api::V1::ApplicationSerializer
2
2
  set_type "scaffolding/completely_concrete/tangible_thing"
3
+ singleton_class.include Rails.application.routes.url_helpers
3
4
 
4
5
  attributes :id,
5
6
  :absolutely_abstract_creative_concept_id,
@@ -25,5 +26,12 @@ class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingSerializer < Api::V
25
26
  :created_at,
26
27
  :updated_at
27
28
 
29
+ # 🚅 skip this section when scaffolding.
30
+ attribute :file_field_value do |object|
31
+ rails_blob_path(object.file_field_value, disposition: "attachment", only_path: true) if object.file_field_value.attached?
32
+ end
33
+ # 🚅 stop any skipping we're doing now.
34
+ # 🚅 super scaffolding will insert file-related logic above this line.
35
+
28
36
  belongs_to :absolutely_abstract_creative_concept, serializer: Api::V1::Scaffolding::AbsolutelyAbstract::CreativeConceptSerializer
29
37
  end
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module SuperScaffolding
3
- VERSION = "1.0.34"
3
+ VERSION = "1.0.37"
4
4
  end
5
5
  end
@@ -107,6 +107,7 @@ class Scaffolding::BlockManipulator
107
107
  insert_line(block_content[1], block_end + 1)
108
108
  end
109
109
 
110
+ # TODO: Delete this because it only really needs to be in the FileManipulator
110
111
  def write
111
112
  File.write(@filepath, @lines.join)
112
113
  end
@@ -160,6 +160,14 @@ class Scaffolding::ClassNamesTransformer
160
160
  parent_in_namespace_class_name.titlecase.pluralize
161
161
  when "Tangible Things"
162
162
  in_namespace_class_name.titlecase.pluralize
163
+ when "Creative concepts"
164
+ parent_in_namespace_class_name.titlecase.downcase.capitalize.pluralize
165
+ when "Tangible things"
166
+ in_namespace_class_name.titlecase.downcase.capitalize.pluralize
167
+ when "creative concepts"
168
+ parent_in_namespace_class_name.titlecase.downcase.pluralize
169
+ when "tangible things"
170
+ in_namespace_class_name.titlecase.downcase.pluralize
163
171
  when "creative-concepts"
164
172
  parent_in_namespace_class_name.underscore.gsub(/[\/_]/, "-").pluralize
165
173
  when "tangible-things"
@@ -173,6 +181,14 @@ class Scaffolding::ClassNamesTransformer
173
181
  parent_in_namespace_class_name.titlecase
174
182
  when "Tangible Thing"
175
183
  in_namespace_class_name.titlecase
184
+ when "Creative concept"
185
+ parent_in_namespace_class_name.titlecase.downcase.capitalize
186
+ when "Tangible thing"
187
+ in_namespace_class_name.titlecase.downcase.capitalize
188
+ when "creative concept"
189
+ parent_in_namespace_class_name.titlecase.downcase
190
+ when "tangible thing"
191
+ in_namespace_class_name.titlecase.downcase
176
192
  when "creative-concept"
177
193
  parent_in_namespace_class_name.underscore.gsub(/[\/_]/, "-")
178
194
  when "tangible-thing"
@@ -0,0 +1,71 @@
1
+ require "scaffolding/block_manipulator"
2
+
3
+ # TODO: If we move this and the BlockManipulator into their own gems,
4
+ # we can probably call these methods with something shorter without `Scaffolding::`.
5
+ module Scaffolding::FileManipulator
6
+ # TODO: The block_manipulator shouldn't be an instance variable.
7
+ def self.find(lines, needle, within = nil, block_manipulator)
8
+ lines_within(lines, within, block_manipulator).each_with_index do |line, line_number|
9
+ return (within + (within ? 1 : 0) + line_number) if line.match?(needle)
10
+ end
11
+ nil
12
+ end
13
+
14
+ # TODO: The block_manipulator shouldn't be an instance variable.
15
+ def self.lines_within(lines, within, block_manipulator)
16
+ return lines unless within
17
+ lines[(within + 1)..(block_manipulator.find_block_end(starting_from: within, lines: lines) + 1)]
18
+ end
19
+
20
+ def self.replace_line_in_file(file, content, in_place_of)
21
+ target_file_content = File.read(file)
22
+
23
+ if target_file_content.include?(content)
24
+ puts "No need to update '#{file}'. It already has '#{content}'."
25
+ else
26
+ puts "Updating '#{file}'."
27
+ target_file_content.gsub!(in_place_of, content)
28
+ File.write(file, target_file_content)
29
+ end
30
+ end
31
+
32
+ # Pass in an array where this content should be inserted within the yml file.
33
+ # For example, to add content to admin.models pass in [:admin, :models]
34
+ def self.add_line_to_yml_file(file, content, location_array)
35
+ # First check that the given location array actually exists in the yml file:
36
+ yml = YAML.safe_load(File.read(file))
37
+ location_array.map!(&:to_s)
38
+
39
+ # TODO: Raise an error if we're returning nil.
40
+ return nil if yml.dig(*location_array).nil?
41
+
42
+ content += "\n" unless content[-1] == "\n"
43
+ # Find the location in the file where the location_array is
44
+ lines = File.readlines(file)
45
+ current_needle = location_array.shift.to_s
46
+ current_space = ""
47
+ insert_after = 1
48
+ lines.each_with_index do |line, index|
49
+ break if current_needle.nil?
50
+ if line.strip == current_needle + ":"
51
+ current_needle = location_array.shift.to_s
52
+ insert_after = index
53
+ current_space = line.match(/\s+/).to_s
54
+ end
55
+ end
56
+ new_lines = []
57
+ current_space += " "
58
+ lines.each_with_index do |line, index|
59
+ new_lines << line
60
+ new_lines << current_space + content if index == insert_after
61
+ end
62
+ File.write(file, new_lines.join)
63
+ end
64
+
65
+ def self.write(file_name, lines)
66
+ puts "Updating '#{file_name}'."
67
+ File.open(file_name, "w+") do |file|
68
+ file.puts(lines.join.strip + "\n")
69
+ end
70
+ end
71
+ end
@@ -82,6 +82,7 @@ class Scaffolding::RoutesFileManipulator
82
82
  results
83
83
  end
84
84
 
85
+ # TODO: Remove this and use the BlockManipulator
85
86
  def insert_before(new_lines, line_number, options = {})
86
87
  options[:indent] ||= false
87
88
  before = lines[0..(line_number - 1)]
@@ -90,6 +91,7 @@ class Scaffolding::RoutesFileManipulator
90
91
  self.lines = before + (options[:prepend_newline] ? ["\n"] : []) + new_lines + after
91
92
  end
92
93
 
94
+ # TODO: Remove this and use the BlockManipulator
93
95
  def insert_after(new_lines, line_number, options = {})
94
96
  options[:indent] ||= false
95
97
  before = lines[0..line_number]
@@ -164,21 +166,13 @@ class Scaffolding::RoutesFileManipulator
164
166
  namespace_block_start.present? ? {namespace => namespace_block_start} : {}
165
167
  end
166
168
 
167
- def find(needle, within = nil)
168
- lines_within(within).each_with_index do |line, line_number|
169
- return (within + (within ? 1 : 0) + line_number) if line.match?(needle)
170
- end
171
-
172
- nil
173
- end
174
-
175
169
  def find_in_namespace(needle, namespaces, within = nil, ignore = nil)
176
170
  if namespaces.any?
177
171
  namespace_lines = find_namespaces(namespaces, within)
178
172
  within = namespace_lines[namespaces.last]
179
173
  end
180
174
 
181
- lines_within(within).each_with_index do |line, line_number|
175
+ Scaffolding::FileManipulator.lines_within(lines, within, block_manipulator).each_with_index do |line, line_number|
182
176
  # + 2 because line_number starts from 0, and within starts one line after
183
177
  actual_line_number = (within + line_number + 2)
184
178
 
@@ -232,7 +226,7 @@ class Scaffolding::RoutesFileManipulator
232
226
  # However, will not find namespace blocks inside namespace blocks.
233
227
  def top_level_namespace_block_lines(within)
234
228
  local_namespace_blocks = []
235
- lines_within(within).each do |line|
229
+ Scaffolding::FileManipulator.lines_within(lines, within, block_manipulator).each do |line|
236
230
  # i.e. - Retrieve "foo" from "namespace :foo do"
237
231
  match_data = line.match(/(\s*namespace\s:)(.*)(\sdo$)/)
238
232
 
@@ -286,11 +280,6 @@ class Scaffolding::RoutesFileManipulator
286
280
  find_or_convert_resource_block(parts.last, options)
287
281
  end
288
282
 
289
- def lines_within(within)
290
- return lines unless within
291
- lines[(within + 1)..(block_manipulator.find_block_end(starting_from: within, lines: lines) + 1)]
292
- end
293
-
294
283
  def find_or_convert_resource_block(parent_resource, options = {})
295
284
  unless find_resource_block([parent_resource], options)
296
285
  if (resource_line_number = find_resource([parent_resource], options))
@@ -310,6 +299,7 @@ class Scaffolding::RoutesFileManipulator
310
299
  within
311
300
  end
312
301
 
302
+ # TODO: Remove this and use the BlockManipulator
313
303
  def insert(lines_to_add, within)
314
304
  insertion_line = block_manipulator.find_block_end(starting_from: within, lines: lines)
315
305
  result_line = insertion_line
@@ -343,7 +333,7 @@ class Scaffolding::RoutesFileManipulator
343
333
  # add the new resource within that namespace.
344
334
  line = "scope module: '#{parent_resource}' do"
345
335
  # TODO you haven't tested this yet.
346
- unless (scope_within = find(/#{line}/, parent_within))
336
+ unless (scope_within = Scaffolding::FileManipulator.find(lines, /#{line}/, parent_within, block_manipulator))
347
337
  scope_within = insert([line, "end"], parent_within)
348
338
  end
349
339
 
@@ -399,11 +389,4 @@ class Scaffolding::RoutesFileManipulator
399
389
  return if concerns.empty?
400
390
  "concerns: #{concerns}"
401
391
  end
402
-
403
- def write
404
- puts "Updating '#{@filename}'."
405
- File.open(@filename, "w+") do |file|
406
- file.puts(lines.join.strip + "\n")
407
- end
408
- end
409
392
  end
@@ -1,10 +1,17 @@
1
1
  require "indefinite_article"
2
2
  require "yaml"
3
+ require "scaffolding/file_manipulator"
3
4
  require "scaffolding/class_names_transformer"
4
5
 
5
6
  class Scaffolding::Transformer
6
7
  attr_accessor :child, :parent, :parents, :class_names_transformer, :cli_options, :additional_steps, :namespace, :suppress_could_not_find
7
8
 
9
+ def code_for_child_on_parent_show_page
10
+ end
11
+
12
+ def update_models_abstract_class
13
+ end
14
+
8
15
  def initialize(child, parents, cli_options = {})
9
16
  self.child = child
10
17
  self.parent = parents.first
@@ -20,6 +27,7 @@ class Scaffolding::Transformer
20
27
  RUBY_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will insert new fields above this line."
21
28
  RUBY_ADDITIONAL_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will also insert new fields above this line."
22
29
  RUBY_EVEN_MORE_NEW_FIELDS_HOOK = "# 🚅 super scaffolding will additionally insert new fields above this line."
30
+ RUBY_FILES_HOOK = "# 🚅 super scaffolding will insert file-related logic above this line."
23
31
  ENDPOINTS_HOOK = "# 🚅 super scaffolding will mount new endpoints above this line."
24
32
  ERB_NEW_FIELDS_HOOK = "<%#{RUBY_NEW_FIELDS_HOOK} %>"
25
33
  CONCERNS_HOOK = "# 🚅 add concerns above."
@@ -89,6 +97,10 @@ class Scaffolding::Transformer
89
97
  "tangible-things",
90
98
  "Creative Concepts",
91
99
  "Tangible Things",
100
+ "Creative concepts",
101
+ "Tangible things",
102
+ "creative concepts",
103
+ "tangible things",
92
104
 
93
105
  # just class name plural.
94
106
  "creative_concept",
@@ -97,6 +109,10 @@ class Scaffolding::Transformer
97
109
  "tangible-thing",
98
110
  "Creative Concept",
99
111
  "Tangible Thing",
112
+ "Creative concept",
113
+ "Tangible thing",
114
+ "creative concept",
115
+ "tangible thing",
100
116
 
101
117
  # Account namespace vs. others.
102
118
  ":account",
@@ -235,36 +251,6 @@ class Scaffolding::Transformer
235
251
  end
236
252
  end
237
253
 
238
- # pass in an array where this content should be inserted within the yml file. For example, to add content
239
- # to admin.models pass in [:admin, :models]
240
- def add_line_to_yml_file(file, content, location_array)
241
- # First check that the given location array actually exists in the yml file:
242
- yml = YAML.safe_load(File.read(file))
243
- location_array.map!(&:to_s)
244
- return nil if yml.dig(*location_array).nil? # Should we raise an error?
245
- content += "\n" unless content[-1] == "\n"
246
- # Find the location in the file where the location_array is
247
- lines = File.readlines(file)
248
- current_needle = location_array.shift.to_s
249
- current_space = ""
250
- insert_after = 1
251
- lines.each_with_index do |line, index|
252
- break if current_needle.nil?
253
- if line.strip == current_needle + ":"
254
- current_needle = location_array.shift.to_s
255
- insert_after = index
256
- current_space = line.match(/\s+/).to_s
257
- end
258
- end
259
- new_lines = []
260
- current_space += " "
261
- lines.each_with_index do |line, index|
262
- new_lines << line
263
- new_lines << current_space + content if index == insert_after
264
- end
265
- File.write(file, new_lines.join)
266
- end
267
-
268
254
  def add_line_to_file(file, content, hook, options = {})
269
255
  increase_indent = options[:increase_indent]
270
256
  add_before = options[:add_before]
@@ -346,23 +332,11 @@ class Scaffolding::Transformer
346
332
  add_line_to_file(file, content, hook, options)
347
333
  end
348
334
 
349
- def replace_line_in_file(file, content, in_place_of)
350
- target_file_content = File.read(file)
351
-
352
- if target_file_content.include?(content)
353
- puts "No need to update '#{file}'. It already has '#{content}'."
354
- else
355
- puts "Updating '#{file}'."
356
- target_file_content.gsub!(in_place_of, content)
357
- File.write(file, target_file_content)
358
- end
359
- end
360
-
361
335
  def scaffold_replace_line_in_file(file, content, in_place_of)
362
336
  file = transform_string(file)
363
337
  # we specifically don't transform the content, we assume a builder function created this content.
364
338
  in_place_of = transform_string(in_place_of)
365
- replace_line_in_file(file, content, in_place_of)
339
+ Scaffolding::FileManipulator.replace_line_in_file(file, content, in_place_of)
366
340
  end
367
341
 
368
342
  # if class_name isn't specified, we use `child`.
@@ -451,8 +425,8 @@ class Scaffolding::Transformer
451
425
  model_names = class_names || [child]
452
426
  role_file = "./config/models/roles.yml"
453
427
  model_names.each do |model_name|
454
- add_line_to_yml_file(role_file, "#{model_name}: read", [:default, :models])
455
- add_line_to_yml_file(role_file, "#{model_name}: manage", [:admin, :models])
428
+ Scaffolding::FileManipulator.add_line_to_yml_file(role_file, "#{model_name}: read", [:default, :models])
429
+ Scaffolding::FileManipulator.add_line_to_yml_file(role_file, "#{model_name}: manage", [:admin, :models])
456
430
  end
457
431
  end
458
432
 
@@ -480,7 +454,7 @@ class Scaffolding::Transformer
480
454
  current_parent = working_parents.pop
481
455
  end
482
456
 
483
- setup_lines << current_transformer.transform_string("@tangible_thing = create(:scaffolding_completely_concrete_tangible_thing, #{previous_assignment})")
457
+ setup_lines << current_transformer.transform_string("@tangible_thing = build(:scaffolding_completely_concrete_tangible_thing, #{previous_assignment})")
484
458
 
485
459
  setup_lines
486
460
  end
@@ -615,7 +589,9 @@ class Scaffolding::Transformer
615
589
  is_id = name.match?(/_id$/)
616
590
  is_ids = name.match?(/_ids$/)
617
591
  # if this is the first attribute of a newly scaffolded model, that field is required.
618
- is_required = attribute_options[:required] || (scaffolding_options[:type] == :crud && index == 0)
592
+ unless type == "file_field"
593
+ is_required = attribute_options[:required] || (scaffolding_options[:type] == :crud && index == 0)
594
+ end
619
595
  is_vanilla = attribute_options&.key?(:vanilla)
620
596
  is_belongs_to = is_id && !is_vanilla
621
597
  is_has_many = is_ids && !is_vanilla
@@ -653,6 +629,8 @@ class Scaffolding::Transformer
653
629
  "date_and_time"
654
630
  when "email_field"
655
631
  "email"
632
+ when "emoji_field"
633
+ "text"
656
634
  when "color_picker"
657
635
  "code"
658
636
  when "text_field"
@@ -661,8 +639,10 @@ class Scaffolding::Transformer
661
639
  "text"
662
640
  when "file_field"
663
641
  "file"
642
+ when "password_field"
643
+ "string"
664
644
  else
665
- raise "Invalid attribute type: #{type}."
645
+ raise "Invalid field type: #{type}."
666
646
  end
667
647
 
668
648
  cell_attributes = if boolean_buttons
@@ -765,13 +745,14 @@ class Scaffolding::Transformer
765
745
  # field on the form.
766
746
  field_attributes = {method: ":#{name}"}
767
747
  field_options = {}
748
+ options = {}
768
749
 
769
750
  if scaffolding_options[:type] == :crud && index == 0
770
751
  field_options[:autofocus] = "true"
771
752
  end
772
753
 
773
754
  if is_id && type == "super_select"
774
- field_options[:include_blank] = "t('.fields.#{name}.placeholder')"
755
+ options[:include_blank] = "t('.fields.#{name}.placeholder')"
775
756
  # add_additional_step :yellow, transform_string("We've added a reference to a `placeholder` to the form for the select or super_select field, but unfortunately earlier versions of the scaffolded locales Yaml don't include a reference to `fields: *fields` under `form`. Please add it, otherwise your form won't be able to locate the appropriate placeholder label.")
776
757
  end
777
758
 
@@ -796,12 +777,19 @@ class Scaffolding::Transformer
796
777
  end
797
778
 
798
779
  # https://stackoverflow.com/questions/21582464/is-there-a-ruby-hashto-s-equivalent-for-the-new-hash-syntax
799
- if field_options.any?
780
+ if field_options.any? || options.any?
800
781
  field_options_key = if ["buttons", "super_select", "options"].include?(type)
782
+ if options.any?
783
+ field_attributes[:options] = "{" + field_options.map { |key, value| "#{key}: #{value}" }.join(", ") + "}"
784
+ end
785
+
801
786
  :html_options
802
787
  else
788
+ field_options.merge!(options)
789
+
803
790
  :options
804
791
  end
792
+
805
793
  field_attributes[field_options_key] = "{" + field_options.map { |key, value| "#{key}: #{value}" }.join(", ") + "}"
806
794
  end
807
795
 
@@ -1038,7 +1026,7 @@ class Scaffolding::Transformer
1038
1026
  # TODO The serializers can't handle these `has_rich_text` attributes.
1039
1027
  unless type == "trix_editor"
1040
1028
  scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.json.jbuilder", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true, suppress_could_not_find: true)
1041
- scaffold_add_line_to_file("./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true)
1029
+ scaffold_add_line_to_file("./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true) unless type == "file_field"
1042
1030
 
1043
1031
  assertion = case type
1044
1032
  when "date_field"
@@ -1047,13 +1035,31 @@ class Scaffolding::Transformer
1047
1035
  "assert_equal DateTime.parse(tangible_thing_data['#{name}']), tangible_thing.#{name}"
1048
1036
  when "file_field"
1049
1037
  # TODO: If we want to use Cloudinary to handle our files, we should make sure we're getting a URL.
1050
- "assert_equal tangible_thing_data['#{name}']['record']['id'], tangible_thing.#{name}.record.id"
1038
+ "assert tangible_thing_data['#{name}'].match?('foo.txt') unless response.status == 201"
1051
1039
  else
1052
1040
  "assert_equal tangible_thing_data['#{name}'], tangible_thing.#{name}"
1053
1041
  end
1054
1042
  scaffold_add_line_to_file("./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_endpoint_test.rb", assertion, RUBY_NEW_FIELDS_HOOK, prepend: true)
1055
1043
  end
1056
1044
 
1045
+ # File fields are handled in a specific way when using the jsonapi-serializer.
1046
+ if type == "file_field"
1047
+ file_name = "./app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb"
1048
+ content = <<~RUBY
1049
+ attribute :#{name} do |object|
1050
+ rails_blob_path(object.#{name}, disposition: "attachment", only_path: true) if object.#{name}.attached?
1051
+ end
1052
+
1053
+ RUBY
1054
+ hook = RUBY_FILES_HOOK
1055
+ scaffold_add_line_to_file(file_name, content, hook, prepend: true)
1056
+
1057
+ # We also want to make sure we attach the dummy file in the endpoint test on setup
1058
+ file_name = "./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_endpoint_test.rb"
1059
+ content = "@#{child.underscore}.#{name} = Rack::Test::UploadedFile.new(\"test/support/foo.txt\")"
1060
+ scaffold_add_line_to_file(file_name, content, hook, prepend: true)
1061
+ end
1062
+
1057
1063
  # scaffold_add_line_to_file("./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_controller_test.rb", "assert_equal tangible_thing_attributes['#{name.gsub('_', '-')}'], tangible_thing.#{name}", RUBY_NEW_FIELDS_HOOK, prepend: true)
1058
1064
 
1059
1065
  if attribute_assignment
@@ -1295,19 +1301,12 @@ class Scaffolding::Transformer
1295
1301
 
1296
1302
  add_has_many_association
1297
1303
 
1298
- # Adds file attachment to factory
1299
- attributes.each do |attribute|
1300
- attribute_name, partial_type = attribute.split(":")
1301
- if partial_type == "file_field"
1302
- content = "#{attribute_name} { Rack::Test::UploadedFile.new(\"test/support/foo.txt\") }"
1303
- scaffold_replace_line_in_file("./test/factories/scaffolding/completely_concrete/tangible_things.rb", content, "#{attribute_name} { nil }")
1304
- end
1305
- end
1306
-
1307
1304
  if class_names_transformer.belongs_to_needs_class_definition?
1308
1305
  scaffold_replace_line_in_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", transform_string("belongs_to :absolutely_abstract_creative_concept, class_name: \"Scaffolding::AbsolutelyAbstract::CreativeConcept\"\n"), transform_string("belongs_to :absolutely_abstract_creative_concept\n"))
1309
1306
  end
1310
1307
 
1308
+ update_models_abstract_class
1309
+
1311
1310
  # add user permissions.
1312
1311
  add_ability_line_to_roles_yml
1313
1312
  end
@@ -1318,7 +1317,12 @@ class Scaffolding::Transformer
1318
1317
 
1319
1318
  # add children to the show page of their parent.
1320
1319
  unless cli_options["skip-parent"] || parent == "None"
1321
- scaffold_add_line_to_file("./app/views/account/scaffolding/absolutely_abstract/creative_concepts/show.html.erb", "<%= render 'account/scaffolding/completely_concrete/tangible_things/index', tangible_things: @creative_concept.completely_concrete_tangible_things, hide_back: true %>", "<%# 🚅 super scaffolding will insert new children above this line. %>", prepend: true)
1320
+ scaffold_add_line_to_file(
1321
+ "./app/views/account/scaffolding/absolutely_abstract/creative_concepts/show.html.erb",
1322
+ code_for_child_on_parent_show_page || "<%= render 'account/scaffolding/completely_concrete/tangible_things/index', tangible_things: @creative_concept.completely_concrete_tangible_things, hide_back: true %>",
1323
+ "<%# 🚅 super scaffolding will insert new children above this line. %>",
1324
+ prepend: true
1325
+ )
1322
1326
  end
1323
1327
 
1324
1328
  unless cli_options["skip-model"]
@@ -1405,7 +1409,7 @@ class Scaffolding::Transformer
1405
1409
  add_additional_step :yellow, "We weren't able to automatically add your `#{routes_namespace}` routes for you. In theory this should be very rare, so if you could reach out on Slack, you could probably provide context that will help us fix whatever the problem was. In the meantime, to add the routes manually, we've got a guide at https://blog.bullettrain.co/nested-namespaced-rails-routing-examples/ ."
1406
1410
  end
1407
1411
 
1408
- routes_manipulator.write
1412
+ Scaffolding::FileManipulator.write("config/routes.rb", routes_manipulator.lines)
1409
1413
  end
1410
1414
 
1411
1415
  unless cli_options["skip-parent"]
@@ -1416,13 +1420,18 @@ class Scaffolding::Transformer
1416
1420
  icon_name = cli_options["sidebar"]
1417
1421
  else
1418
1422
  puts ""
1419
- puts "Hey, models that are scoped directly off of a Team (or nothing) are eligible to be added to the sidebar. Do you want to add this resource to the sidebar menu? (y/N)"
1423
+ puts "Hey, models that are scoped directly off of a Team (or nothing) are eligible to be added to the sidebar."
1424
+ puts "Do you want to add this resource to the sidebar menu? (y/N)"
1420
1425
  response = $stdin.gets.chomp
1421
1426
  if response.downcase[0] == "y"
1422
1427
  puts ""
1423
- puts "OK, great! Let's do this! By default these menu items appear with a puzzle piece, but after you hit enter I'll open two different pages where you can view other icon options. When you find one you like, hover your mouse over it and then come back here and and enter the name of the icon you want to use. (Or hit enter to skip this step.)"
1428
+ puts "OK, great! Let's do this! By default these menu items appear as a #{font_awesome? ? "puzzle piece" : "gift icon"},"
1429
+ puts "but after you hit enter I'll open #{font_awesome? ? "two different pages" : "a page"} where you can view other icon options."
1430
+ puts "When you find one you like, hover your mouse over it and then come back here and"
1431
+ puts "enter the name of the icon you want to use."
1432
+ puts "(Or hit enter when choosing to skip this step.)"
1424
1433
  $stdin.gets.chomp
1425
- if `which open`.present?
1434
+ if (TerminalCommands.macosx? && `which open`.present?) || TerminalCommands.linux?
1426
1435
  TerminalCommands.open_file_or_link("https://themify.me/themify-icons")
1427
1436
  if font_awesome?
1428
1437
  TerminalCommands.open_file_or_link("https://fontawesome.com/icons?d=gallery&s=light")
@@ -1437,8 +1446,18 @@ class Scaffolding::Transformer
1437
1446
  puts ""
1438
1447
  end
1439
1448
  puts ""
1440
- puts "Did you find an icon you wanted to use? Enter the full CSS class here (e.g. 'ti ti-world'#{" or 'fal fa-puzzle-piece'" if font_awesome?}) or hit enter to just use the puzzle piece:"
1441
- icon_name = $stdin.gets.chomp
1449
+
1450
+ loop do
1451
+ puts "Did you find an icon you wanted to use?"
1452
+ puts "Enter the full CSS class here (e.g. 'ti ti-world'#{" or 'fal fa-puzzle-piece'" if font_awesome?}) or hit enter to just use the #{font_awesome? ? "puzzle piece" : "gift icon"}:"
1453
+ icon_name = $stdin.gets.chomp
1454
+ unless icon_name.match?(/ti\s.*/) || icon_name.match?(/fal\s.*/) || icon_name.strip.empty?
1455
+ puts ""
1456
+ puts "Please enter the full CSS class or hit enter."
1457
+ next
1458
+ end
1459
+ break
1460
+ end
1442
1461
  puts ""
1443
1462
  unless icon_name.length > 0 || icon_name.downcase == "y"
1444
1463
  icon_name = "fal fa-puzzle-piece ti ti-gift"
data/lib/scaffolding.rb CHANGED
@@ -8,6 +8,7 @@ module Scaffolding
8
8
  "date_and_time_field",
9
9
  "date_field",
10
10
  "email_field",
11
+ "emoji_field",
11
12
  "file_field",
12
13
  "options",
13
14
  "password_field",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-super_scaffolding
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.34
4
+ version: 1.0.37
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-20 00:00:00.000000000 Z
11
+ date: 2022-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -166,6 +166,7 @@ files:
166
166
  - lib/scaffolding.rb
167
167
  - lib/scaffolding/block_manipulator.rb
168
168
  - lib/scaffolding/class_names_transformer.rb
169
+ - lib/scaffolding/file_manipulator.rb
169
170
  - lib/scaffolding/oauth_providers.rb
170
171
  - lib/scaffolding/routes_file_manipulator.rb
171
172
  - lib/scaffolding/script.rb
@@ -177,7 +178,7 @@ licenses:
177
178
  metadata:
178
179
  homepage_uri: https://github.com/bullet-train-co/bullet_train-super_scaffolding
179
180
  source_code_uri: https://github.com/bullet-train-co/bullet_train-super_scaffolding
180
- post_install_message:
181
+ post_install_message:
181
182
  rdoc_options: []
182
183
  require_paths:
183
184
  - lib
@@ -192,8 +193,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
193
  - !ruby/object:Gem::Version
193
194
  version: '0'
194
195
  requirements: []
195
- rubygems_version: 3.3.7
196
- signing_key:
196
+ rubygems_version: 3.1.6
197
+ signing_key:
197
198
  specification_version: 4
198
199
  summary: Bullet Train Super Scaffolding
199
200
  test_files: []