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 +4 -4
- data/app/controllers/api/v1/scaffolding/completely_concrete/tangible_things_endpoint.rb +1 -0
- data/app/serializers/api/v1/scaffolding/completely_concrete/tangible_thing_serializer.rb +8 -0
- data/lib/bullet_train/super_scaffolding/version.rb +1 -1
- data/lib/scaffolding/block_manipulator.rb +1 -0
- data/lib/scaffolding/class_names_transformer.rb +16 -0
- data/lib/scaffolding/file_manipulator.rb +71 -0
- data/lib/scaffolding/routes_file_manipulator.rb +6 -23
- data/lib/scaffolding/transformer.rb +87 -68
- data/lib/scaffolding.rb +1 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ca43f2f490c937c87fcc1493b3e194d56f2e39bccd57e01ba7eda9bbaa230fa
|
4
|
+
data.tar.gz: f027670522cf4faf29a93bf237874ccffcee91f88fece103522ec2e0c0e21508
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
@@ -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 =
|
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
|
-
|
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
|
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
|
-
|
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
|
-
"
|
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(
|
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.
|
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.
|
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
|
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
|
-
|
1441
|
-
|
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
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.
|
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-
|
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.
|
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: []
|