-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run rails generate
commands automatically when Super Scaffolding
#547
Changes from all commits
90691fe
3ac77a2
a73edaa
0d90b85
eaaabf4
5b45c71
4d66db6
e6aa173
9f6b314
bd6ff3e
ab54117
2396d18
5a834cd
206972c
79b44f2
f2f0338
8265e38
3d59e5e
cca2fc5
4d0ffbd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,28 @@ | |
|
||
require_relative "../bullet_train/terminal_commands" | ||
|
||
FIELD_PARTIALS = { | ||
address_field: "string", | ||
boolean: "boolean", | ||
buttons: "string", | ||
cloudinary_image: "string", | ||
color_picker: "string", | ||
date_and_time_field: "datetime", | ||
date_field: "date", | ||
email_field: "string", | ||
emoji_field: "string", | ||
file_field: "attachment", | ||
image: "attachment", | ||
options: "string", | ||
password_field: "string", | ||
phone_field: "string", | ||
super_select: "string", | ||
text_area: "text", | ||
text_field: "string", | ||
number_field: "integer", | ||
trix_editor: "text" | ||
} | ||
|
||
# filter out options. | ||
argv = [] | ||
@options = {} | ||
|
@@ -29,10 +51,49 @@ def standard_protip | |
end | ||
|
||
def check_required_options_for_attributes(scaffolding_type, attributes, child, parent = nil) | ||
tableized_parent = nil | ||
|
||
# Ensure the parent attribute name has the proper namespacing for adding as a foreign key. | ||
if parent.present? | ||
if child.include?("::") && parent.include?("::") | ||
child_parts = child.split("::") | ||
parent_parts = parent.split("::") | ||
child_parts_dup = child_parts.dup | ||
parent_parts_dup = parent_parts.dup | ||
|
||
# Pop off however many spaces match. | ||
child_parts_dup.each.with_index do |child_part, idx| | ||
if child_part == parent_parts_dup[idx] | ||
child_parts.shift | ||
parent_parts.shift | ||
else | ||
tableized_parent = parent_parts.map(&:downcase).join("_") | ||
break | ||
end | ||
end | ||
end | ||
# In case we're not working with namespaces, just tableize the parent as is. | ||
tableized_parent ||= parent.tableize.singularize.tr("/", "_") if parent.present? | ||
end | ||
|
||
generation_command = case scaffolding_type | ||
when "crud" | ||
"bin/rails generate model #{child} #{tableized_parent}:references" | ||
when "crud-field" | ||
"" # This is blank so we can create the proper migration name first after we get the attributes. | ||
end | ||
|
||
# Even if there are attributes passed to the scaffolder, | ||
# They may already exist in previous migrations, so we | ||
# only register ones that need to be generated. | ||
# i.e. - *_ids attributes in the join-model scaffolder. | ||
attributes_to_generate = [] | ||
|
||
attributes.each do |attribute| | ||
parts = attribute.split(":") | ||
name = parts.shift | ||
type = parts.join(":") | ||
type_without_option = type.gsub(/{.*}/, "") | ||
|
||
unless Scaffolding.valid_attribute_type?(type) | ||
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 | |
{} | ||
end | ||
|
||
data_type = if type == "image" && cloudinary_enabled? | ||
"string" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, here's that special case I mentioned above. Maybe we remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Right, I was planning on leaving it here for backwards compatibility. However, if we were to delete it, it technically wouldn't be breaking anything so I don't feel too strongly either way right now about leaving it or deleting it. |
||
elsif attribute_options[:multiple] | ||
case type | ||
when "file" | ||
"attachments" | ||
else | ||
"jsonb" | ||
end | ||
else | ||
FIELD_PARTIALS[type_without_option.to_sym] | ||
end | ||
|
||
if name.match?(/_id$/) || name.match?(/_ids$/) | ||
attribute_options ||= {} | ||
unless attribute_options[:vanilla] | ||
|
@@ -85,6 +159,30 @@ def check_required_options_for_attributes(scaffolding_type, attributes, child, p | |
end | ||
end | ||
end | ||
|
||
# TODO: Is there ever a case that we want this to be a string? | ||
data_type = "references" if name.match?(/_id$/) | ||
|
||
# For join models, we don't want to generate a migration when | ||
# running the crud-field scaffolder in the last step, so we skip *_ids. | ||
unless name.match?(/_ids$/) | ||
generation_command += " #{name_without_id || name}:#{data_type}" | ||
attributes_to_generate << name | ||
end | ||
end | ||
|
||
# Generate the models/migrations with the attributes passed. | ||
if attributes_to_generate.any? | ||
case scaffolding_type | ||
# "join-model" is not here because the `rails g` command is written inline in its own scaffolder. | ||
when "crud" | ||
puts "Generating #{child} model with '#{generation_command}'".green | ||
when "crud-field" | ||
generation_command = "bin/rails generate migration add_#{attributes_to_generate.join("_and_")}_to_#{child.tableize.tr("/", "_")}#{generation_command}" | ||
puts "Adding new fields to #{child} with '#{generation_command}'".green | ||
end | ||
puts "" | ||
`#{generation_command}` unless @options["skip-migration-generation"] | ||
end | ||
end | ||
|
||
|
@@ -120,36 +218,16 @@ def show_usage | |
when "--field-partials" | ||
puts "Bullet Train uses the following field partials for Super Scaffolding".blue | ||
puts "" | ||
field_partials = { | ||
address_field: "string", | ||
boolean: "boolean", | ||
buttons: "string", | ||
cloudinary_image: "string", | ||
color_picker: "string", | ||
date_and_time_field: "datetime", | ||
date_field: "date_field", | ||
email_field: "string", | ||
emoji_field: "string", | ||
file_field: "attachment", | ||
options: "string", | ||
password_field: "string", | ||
phone_field: "string", | ||
super_select: "string", | ||
text_area: "text", | ||
text_field: "string", | ||
number_field: "integer", | ||
trix_editor: "text" | ||
} | ||
|
||
max_name_length = 0 | ||
field_partials.each do |key, value| | ||
FIELD_PARTIALS.each do |key, value| | ||
if key.to_s.length > max_name_length | ||
max_name_length = key.to_s.length | ||
end | ||
end | ||
|
||
printf "\t%#{max_name_length}s:Data Type\n".bold, "Field Partial Name" | ||
field_partials.each { |key, value| printf "\t%#{max_name_length}s:#{value}\n", key } | ||
FIELD_PARTIALS.each { |key, value| printf "\t%#{max_name_length}s:#{value}\n", key } | ||
|
||
puts "" | ||
puts "For more details, check out the documentation:" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be
active_storage_image
? Or should we removecloudinary_image
above and then haveimage
be a special case where we don't do a direct lookup, but instead check whether Cloudinary is active?