bullet_train-super_scaffolding 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b401a89cc8733d82b955c7a8364fd8d4f5baf0db63ab606dcbcf60686c5ba33
4
- data.tar.gz: 8368208e9fb8fb26726b09baaf5dccc9990f6791c143ceedac03e82d846e2615
3
+ metadata.gz: deba742f563b6d3def090a3b04a3a8efdcac8750bc2828575cd6cc0804ae5390
4
+ data.tar.gz: 5d15eae1ce2d7770ee8ef10cd49022974fd2dd746a10cee22dc032b7bea38b74
5
5
  SHA512:
6
- metadata.gz: 11500e4a8fd203a0f84d3ba2235293c4195be193920f4c646c4cd72a9bd01972bb23c3f3b07b5c9798c5a9db98b8460c9f8637e348f45608a512acfcbc7258fe
7
- data.tar.gz: da6529b8e728292c20192119a374693b5b9c9d2603d41c75014e30a91eaeda172ddefe48287d56abbb7a8344247e01e62cab6e394332a414cf62baad93ef6777
6
+ metadata.gz: 601210d754a40a9d0d62555ba661a1ba35463e68aef0b2adbac930cd215def4bed94288783343bb68232a987980b8f6bc816e2ac4399469cecf4300e03928b12
7
+ data.tar.gz: c1b8e0cc87d2a648b589fc00eb3eaba87699591f04e9e4daf47b1cff0356cc9bb8a207aecbf10ac28135882e853ebaa3e26dd8d66e371ea0332dd581f0acb4a9
@@ -51,6 +51,11 @@ module BulletTrain
51
51
  end
52
52
  end
53
53
 
54
+ # get all the attributes.
55
+ attributes = argv[2..]
56
+
57
+ check_required_options_for_attributes("crud", attributes, child, parent)
58
+
54
59
  # `tr` here compensates for namespaced models (i.e. - `Projects::Deliverable` to `projects/deliverable`).
55
60
  parent_reference = parent_without_namespace.tableize.singularize.tr("/", "_")
56
61
  tableized_child = child.tableize.tr("/", "_")
@@ -82,11 +87,6 @@ module BulletTrain
82
87
  "bin/super-scaffold crud Section Page,Site,Team title:text body:text\n"
83
88
  end
84
89
 
85
- # get all the attributes.
86
- attributes = argv[2..]
87
-
88
- check_required_options_for_attributes("crud", attributes, child, parent)
89
-
90
90
  transformer = Scaffolding::Transformer.new(child, parents, @options)
91
91
  transformer.scaffold_crud(attributes)
92
92
 
@@ -44,6 +44,16 @@ module BulletTrain
44
44
  # There should only be two attributes.
45
45
  attributes = [argv[1], argv[2]]
46
46
 
47
+ unless @options["skip-migration-generation"]
48
+ attributes_without_options = attributes.map { |attribute| attribute.gsub(/{.*}$/, "") }
49
+ attributes_without_id = attributes_without_options.map { |attribute| attribute.gsub(/_id$/, "") }
50
+ attributes_with_references = attributes_without_id.map { |attribute| attribute + ":references" }
51
+
52
+ generation_command = "bin/rails generate model #{child} #{attributes_with_references.join(" ")}"
53
+ puts "Generating model with '#{generation_command}'".green
54
+ `#{generation_command}`
55
+ end
56
+
47
57
  # Pretend we're doing a `super_select` scaffolding because it will do the correct thing.
48
58
  attributes = attributes.map { |attribute| attribute.gsub("{", ":super_select{") }
49
59
  attributes = attributes.map { |attribute| attribute.gsub("}", ",required}") }
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module SuperScaffolding
3
- VERSION = "1.5.1"
3
+ VERSION = "1.6.0"
4
4
  end
5
5
  end
@@ -167,6 +167,8 @@ class Scaffolding::Attribute
167
167
  "text"
168
168
  when "number_field"
169
169
  "number"
170
+ when "address_field"
171
+ "address"
170
172
  else
171
173
  raise "Invalid field type: #{type}."
172
174
  end
@@ -7,6 +7,28 @@ require "scaffolding/routes_file_manipulator"
7
7
 
8
8
  require_relative "../bullet_train/terminal_commands"
9
9
 
10
+ FIELD_PARTIALS = {
11
+ address_field: nil,
12
+ boolean: "boolean",
13
+ buttons: "string",
14
+ cloudinary_image: "string",
15
+ color_picker: "string",
16
+ date_and_time_field: "datetime",
17
+ date_field: "date",
18
+ email_field: "string",
19
+ emoji_field: "string",
20
+ file_field: "attachment",
21
+ image: "attachment",
22
+ options: "string",
23
+ password_field: "string",
24
+ phone_field: "string",
25
+ super_select: "string",
26
+ text_area: "text",
27
+ text_field: "string",
28
+ number_field: "integer",
29
+ trix_editor: "text"
30
+ }
31
+
10
32
  # filter out options.
11
33
  argv = []
12
34
  @options = {}
@@ -29,10 +51,49 @@ def standard_protip
29
51
  end
30
52
 
31
53
  def check_required_options_for_attributes(scaffolding_type, attributes, child, parent = nil)
54
+ tableized_parent = nil
55
+
56
+ # Ensure the parent attribute name has the proper namespacing for adding as a foreign key.
57
+ if parent.present?
58
+ if child.include?("::") && parent.include?("::")
59
+ child_parts = child.split("::")
60
+ parent_parts = parent.split("::")
61
+ child_parts_dup = child_parts.dup
62
+ parent_parts_dup = parent_parts.dup
63
+
64
+ # Pop off however many spaces match.
65
+ child_parts_dup.each.with_index do |child_part, idx|
66
+ if child_part == parent_parts_dup[idx]
67
+ child_parts.shift
68
+ parent_parts.shift
69
+ else
70
+ tableized_parent = parent_parts.map(&:downcase).join("_")
71
+ break
72
+ end
73
+ end
74
+ end
75
+ # In case we're not working with namespaces, just tableize the parent as is.
76
+ tableized_parent ||= parent.tableize.singularize.tr("/", "_") if parent.present?
77
+ end
78
+
79
+ generation_command = case scaffolding_type
80
+ when "crud"
81
+ "bin/rails generate model #{child} #{tableized_parent}:references"
82
+ when "crud-field"
83
+ "" # This is blank so we can create the proper migration name first after we get the attributes.
84
+ end
85
+
86
+ # Even if there are attributes passed to the scaffolder,
87
+ # They may already exist in previous migrations, so we
88
+ # only register ones that need to be generated.
89
+ # i.e. - *_ids attributes in the join-model scaffolder.
90
+ attributes_to_generate = []
91
+
32
92
  attributes.each do |attribute|
33
93
  parts = attribute.split(":")
34
94
  name = parts.shift
35
95
  type = parts.join(":")
96
+ type_without_option = type.gsub(/{.*}/, "")
36
97
 
37
98
  unless Scaffolding.valid_attribute_type?(type)
38
99
  raise "You have entered an invalid attribute type: #{type}. General data types are used when creating new models, but Bullet Train " \
@@ -53,6 +114,19 @@ def check_required_options_for_attributes(scaffolding_type, attributes, child, p
53
114
  {}
54
115
  end
55
116
 
117
+ data_type = if type == "image" && cloudinary_enabled?
118
+ "string"
119
+ elsif attribute_options[:multiple]
120
+ case type
121
+ when "file"
122
+ "attachments"
123
+ else
124
+ "jsonb"
125
+ end
126
+ else
127
+ FIELD_PARTIALS[type_without_option.to_sym]
128
+ end
129
+
56
130
  if name.match?(/_id$/) || name.match?(/_ids$/)
57
131
  attribute_options ||= {}
58
132
  unless attribute_options[:vanilla]
@@ -85,6 +159,31 @@ def check_required_options_for_attributes(scaffolding_type, attributes, child, p
85
159
  end
86
160
  end
87
161
  end
162
+
163
+ # TODO: Is there ever a case that we want this to be a string?
164
+ data_type = "references" if name.match?(/_id$/)
165
+
166
+ # For join models, we don't want to generate a migration when
167
+ # running the crud-field scaffolder in the last step, so we skip *_ids.
168
+ # Addresses belong_to :addressable, so they don't hae to be represented in a migration.
169
+ unless name.match?(/_ids$/) || data_type.nil?
170
+ generation_command += " #{name_without_id || name}:#{data_type}"
171
+ attributes_to_generate << name
172
+ end
173
+ end
174
+
175
+ # Generate the models/migrations with the attributes passed.
176
+ if attributes_to_generate.any?
177
+ case scaffolding_type
178
+ # "join-model" is not here because the `rails g` command is written inline in its own scaffolder.
179
+ when "crud"
180
+ puts "Generating #{child} model with '#{generation_command}'".green
181
+ when "crud-field"
182
+ generation_command = "bin/rails generate migration add_#{attributes_to_generate.join("_and_")}_to_#{child.tableize.tr("/", "_")}#{generation_command}"
183
+ puts "Adding new fields to #{child} with '#{generation_command}'".green
184
+ end
185
+ puts ""
186
+ `#{generation_command}` unless @options["skip-migration-generation"]
88
187
  end
89
188
  end
90
189
 
@@ -120,35 +219,16 @@ elsif ARGV.first.present?
120
219
  when "--field-partials"
121
220
  puts "Bullet Train uses the following field partials for Super Scaffolding".blue
122
221
  puts ""
123
- field_partials = {
124
- boolean: "boolean",
125
- buttons: "string",
126
- cloudinary_image: "string",
127
- color_picker: "string",
128
- date_and_time_field: "datetime",
129
- date_field: "date_field",
130
- email_field: "string",
131
- emoji_field: "string",
132
- file_field: "attachment",
133
- options: "string",
134
- password_field: "string",
135
- phone_field: "string",
136
- super_select: "string",
137
- text_area: "text",
138
- text_field: "string",
139
- number_field: "integer",
140
- trix_editor: "text"
141
- }
142
222
 
143
223
  max_name_length = 0
144
- field_partials.each do |key, value|
224
+ FIELD_PARTIALS.each do |key, value|
145
225
  if key.to_s.length > max_name_length
146
226
  max_name_length = key.to_s.length
147
227
  end
148
228
  end
149
229
 
150
230
  printf "\t%#{max_name_length}s:Data Type\n".bold, "Field Partial Name"
151
- field_partials.each { |key, value| printf "\t%#{max_name_length}s:#{value}\n", key }
231
+ FIELD_PARTIALS.each { |key, value| printf "\t%#{max_name_length}s:#{value}\n", key }
152
232
 
153
233
  puts ""
154
234
  puts "For more details, check out the documentation:"
@@ -102,7 +102,7 @@ class Scaffolding::Transformer
102
102
  "absolutely_abstract/creative_concepts",
103
103
  "completely_concrete/tangible_things",
104
104
  "absolutely-abstract-creative-concepts",
105
- "completely-concrete-tangible-things",
105
+ "completely-concrete-tangible-things"
106
106
  ]
107
107
 
108
108
  class_name = [
@@ -115,7 +115,7 @@ class Scaffolding::Transformer
115
115
  "Creative concepts",
116
116
  "Tangible things",
117
117
  "creative concepts",
118
- "tangible things",
118
+ "tangible things"
119
119
  ]
120
120
 
121
121
  (
@@ -870,8 +870,11 @@ class Scaffolding::Transformer
870
870
  <td#{cell_attributes}><%= render 'shared/attributes/#{attribute.partial_name}', attribute: :#{attribute.is_vanilla? ? attribute.name : attribute.name_without_id_suffix}#{", #{table_cell_options.join(", ")}" if table_cell_options.any?} %></td>
871
871
  ERB
872
872
 
873
- if attribute.type == "password_field"
873
+ case attribute.type
874
+ when "password_field"
874
875
  field_content.gsub!(/\s%>/, ", options: { password: true } %>")
876
+ when "address_field"
877
+ field_content.gsub!(/\s%>/, ", one_line: true %>")
875
878
  end
876
879
 
877
880
  unless ["Team", "User"].include?(child)
@@ -958,6 +961,20 @@ class Scaffolding::Transformer
958
961
  if attribute.type == "file_field"
959
962
  scaffold_add_line_to_file(file, "#{attribute.name}_removal: [],", RUBY_NEW_ARRAYS_HOOK, prepend: true)
960
963
  end
964
+ elsif attribute.type == "address_field"
965
+ address_strong_params = <<~RUBY
966
+ #{attribute.name}_attributes: [
967
+ :id,
968
+ :_destroy,
969
+ :address_one,
970
+ :address_two,
971
+ :city,
972
+ :country_id,
973
+ :region_id,
974
+ :postal_code
975
+ ],
976
+ RUBY
977
+ scaffold_add_line_to_file(file, address_strong_params, RUBY_NEW_ARRAYS_HOOK, prepend: true)
961
978
  else
962
979
  scaffold_add_line_to_file(file, ":#{attribute.name},", RUBY_NEW_FIELDS_HOOK, prepend: true)
963
980
  if attribute.type == "file_field"
@@ -969,6 +986,28 @@ class Scaffolding::Transformer
969
986
  scaffold_add_line_to_file("./app/controllers/account/scaffolding/completely_concrete/tangible_things_controller.rb", attribute.special_processing, RUBY_NEW_FIELDS_PROCESSING_HOOK, prepend: true) if attribute.special_processing
970
987
  end
971
988
 
989
+ #
990
+ # ASSOCIATED MODELS
991
+ #
992
+
993
+ unless cli_options["skip-form"] || attribute.options[:readonly]
994
+
995
+ # set default values for associated models.
996
+ case attribute.type
997
+ when "address_field"
998
+ scaffold_add_line_to_file("./app/controllers/account/scaffolding/completely_concrete/tangible_things_controller.rb", "before_action :set_default_#{attribute.name}, except: :index", "ApplicationController", increase_indent: true)
999
+
1000
+ method_content = <<~RUBY
1001
+
1002
+ def set_default_#{attribute.name}
1003
+ @tangible_thing.#{attribute.name} ||= Address.new
1004
+ end
1005
+ RUBY
1006
+ scaffold_add_line_to_file("./app/controllers/account/scaffolding/completely_concrete/tangible_things_controller.rb", method_content, "end", prepend: true, increase_indent: true, exact_match: true)
1007
+ end
1008
+
1009
+ end
1010
+
972
1011
  #
973
1012
  # API SERIALIZER
974
1013
  #
@@ -1246,6 +1285,9 @@ class Scaffolding::Transformer
1246
1285
  scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", "after_validation :remove_#{attribute.name}, if: :#{attribute.name}_removal?", CALLBACKS_HOOK, prepend: true)
1247
1286
  when "trix_editor"
1248
1287
  scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", "has_rich_text :#{attribute.name}", HAS_ONE_HOOK, prepend: true)
1288
+ when "address_field"
1289
+ scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", "has_one :#{attribute.name}, class_name: \"Address\", as: :addressable", HAS_ONE_HOOK, prepend: true)
1290
+ scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", "accepts_nested_attributes_for :#{attribute.name}", HAS_ONE_HOOK, prepend: true)
1249
1291
  when "buttons"
1250
1292
  if attribute.is_boolean?
1251
1293
  scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", "validates :#{attribute.name}, inclusion: [true, false]", VALIDATIONS_HOOK, prepend: true)
data/lib/scaffolding.rb CHANGED
@@ -7,6 +7,7 @@ module Scaffolding
7
7
 
8
8
  def self.valid_attribute_type?(type)
9
9
  [
10
+ "address_field",
10
11
  "boolean",
11
12
  "buttons",
12
13
  # TODO: We're leaving cloudinary_image here for now for backwards compatibility.
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.5.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-02 00:00:00.000000000 Z
11
+ date: 2023-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: masamune-ast
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.2.1
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: indefinite_article
57
71
  requirement: !ruby/object:Gem::Requirement