bullet_train-super_scaffolding 1.5.1 → 1.6.0

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: 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