rails_steroids 0.5.0 → 0.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: 575fafaef4cda7385ace12ae8c8c6ba3469ca6a8720eb54692240a79739ca6c1
4
- data.tar.gz: 764ba190e5246e78820af6bae9598ab498258133b513f0cc26f7767bd90bb2ee
3
+ metadata.gz: 656c3847e194bf888f0b4c12482d3d7ba06200ab1af54d433bada03401d84398
4
+ data.tar.gz: 7bd0c50707fb1e44a256f09c5645cc1e8410bc0f7f131c20ea8f4cf70f22431b
5
5
  SHA512:
6
- metadata.gz: 73d18703d85c492632f3348941505cd748ff34855f4b293a8127128a5c278b07e7716b1e5f9754d296560846f0ce0304b23e7d0452a71b60b2f119d375a3453b
7
- data.tar.gz: c9e6807f7f94a24e956ba7f1e7c8d0348495168c761f149cb8b573a7882f6bbfd823b90dcde840ffc4fa5ea4a8fea2c801f01d398936b60a5a8a9776fcb06492
6
+ metadata.gz: cce4f6c5f46464d33fb3c9e8721a5d6db48595be7369bba3487882ee3c98c77fa98b57f653d6490254ad0815fed235f0b8c37534e4d4415b0d69d8bb7423bc73
7
+ data.tar.gz: 98e2c27907407481adf9c168116b2cc5e46c992d9c5c12d2f5892f30e41cfe38c9eba051b4208bdef7ba9c8fed0b8e19b5d82f6435335f62fb2497a36f18d19d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.0] - 2024-02-07
4
+
5
+ - New steroid recipe: migration (Create new migration interactively)
6
+
3
7
  ## [0.5.0] - 2024-02-06
4
8
 
5
9
  - New steroid recipe: model (Create new model interactively)
data/README.md CHANGED
@@ -49,6 +49,7 @@ and then enjoy easily entering or selecting options interactively to the questio
49
49
 
50
50
  | Functionality | Command |
51
51
  |---|---|
52
+ |migration|`rails_steroids inject steroid:migration`|
52
53
  |model|`rails_steroids inject steroid:model`|
53
54
  |controller|`rails_steroids inject steroid:controller`|
54
55
  |new_project|`rails_steroids inject steroid:new_project`|
@@ -0,0 +1,21 @@
1
+ Description:
2
+ `steroid:migration` will create Migration interactively.
3
+
4
+ Usage Example:
5
+ # with installed gem
6
+ rails_steroids inject steroid:migration
7
+ # with bundler
8
+ bin/rails g steroid:migration
9
+
10
+ What will this do?:
11
+ Create new Rails migration with configurations selected interactively.
12
+ Current options available to customize are:
13
+ * Create table, Create join table and Drop table
14
+ * Specify columns with column type and some other metadata
15
+ * Column metadata includes:
16
+ - limit for integer, string, text, binary
17
+ - precision and scale for decimal
18
+ - polymorphic for references
19
+ - index and unique index
20
+ - id column, custom join table name for join table creation
21
+ - Addition to original migration generator is we can set default value as well
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tty/prompt'
4
+ require 'rails/version'
5
+ require 'rails/generators/active_record'
6
+ require 'rails/generators/active_record/migration'
7
+
8
+ module Steroid
9
+ class MigrationGenerator < Rails::Generators::Base
10
+ desc "Adds Migration to the application"
11
+ source_root File.expand_path("templates", __dir__)
12
+ include ActiveRecord::Generators::Migration
13
+ include ActiveRecord::Migration::JoinTable
14
+
15
+ def add_migration
16
+ say "Injecting steroid: Migration", :green
17
+ cmd = ["rails generate migration"]
18
+ prompt = TTY::Prompt.new
19
+ boolean_choices = [{name: "yes", value: true}, {name: "no", value: false}]
20
+
21
+ action_choices = [
22
+ {name: 'Create table', value: 'create_table'},
23
+ {name: 'Create join table', value: 'create_join_table'},
24
+ {name: 'Drop table', value: 'drop_table'},
25
+ # {name: 'Modify table columns/index', value: 'modify_table'},
26
+ # {name: 'Add column', value: 'add_column'},
27
+ # {name: 'Remove column', value: 'remove_column'},
28
+ # {name: 'Add index', value: 'add_index'},
29
+ # {name: 'Remove index', value: 'remove_index'},
30
+ ]
31
+ action = prompt.select("What would you like to do?", action_choices)
32
+
33
+ case action
34
+ when 'create_table'
35
+ table_name = prompt.ask("What is the name of table to be created?", required: true) { |q| q.modify :remove }
36
+ @content = content_for_create_table(table_name, collect_columns_data, need_timestamps?)
37
+ migration_template "migration.rb", "#{db_migrate_path}/create_#{table_name}.rb"
38
+ when 'create_join_table'
39
+ table1_name = prompt.ask("What is the name of first table to be joined?", required: true) { |q| q.modify :remove }
40
+ table2_name = prompt.ask("What is the name of second table to be joined?", required: true) { |q| q.modify :remove }
41
+ table_name = prompt.ask("What is the custom name for join table?", default: find_join_table_name(table1_name, table2_name), required: true) { |q| q.modify :remove }
42
+ columns_data = []
43
+ if prompt.select("Add `id` column?", boolean_choices)
44
+ columns_data << {name: 'id', type: 'primary_key'}
45
+ end
46
+ if prompt.select("Add index for #{table1_name} foreign_key?", boolean_choices)
47
+ columns_data << {name: "#{table1_name.singularize}_id", type: 'index'}
48
+ end
49
+ if prompt.select("Add index for #{table2_name} foreign_key?", boolean_choices)
50
+ columns_data << {name: "#{table2_name.singularize}_id", type: 'index'}
51
+ end
52
+ if prompt.select("Add composite index for #{table1_name} and #{table2_name} foreign_key?", boolean_choices)
53
+ uniq_index_option = prompt.select("Unique combination index?", boolean_choices) ? {meta: {unique: true}} : {}
54
+ columns_data << {name: "[:#{table2_name.singularize}_id, :#{table2_name.singularize}_id]", type: 'index'}.merge(uniq_index_option)
55
+ end
56
+ @content = content_for_create_join_table(table1_name, table2_name, table_name, (columns_data + collect_columns_data), need_timestamps?)
57
+ migration_template "migration.rb", "#{db_migrate_path}/create_join_table_#{table_name}.rb"
58
+ when 'drop_table'
59
+ table_name = prompt.ask("What is the name of table to be dropped?", required: true) { |q| q.modify :remove }
60
+ @content = content_for_drop_table(table_name)
61
+ migration_template "migration.rb", "#{db_migrate_path}/drop_#{table_name}.rb"
62
+ # when 'modify_table'
63
+ # table_name = prompt.ask("What is the name of table to add/remove columns?", required: true) { |q| q.modify :remove }
64
+ # columns_to_be_added = collect_columns_data
65
+ # columns_to_be_removed
66
+ # migration_template "migration.rb", "#{db_migrate_path}/drop_#{table_name}.rb"
67
+ # when 'add_column'
68
+ # when 'remove_column'
69
+ # when 'add_index'
70
+ # when 'remove_index'
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def collect_columns_data
77
+ prompt = TTY::Prompt.new
78
+ boolean_choices = [{name: "yes", value: true}, {name: "no", value: false}]
79
+ columns = []
80
+ while prompt.select("Would you like to add model attributes(columns)?", boolean_choices)
81
+ columns_data = { meta: {} }
82
+ column_name = prompt.ask("Specify name of column:", required: true) { |q| q.modify :remove }
83
+
84
+ column_type = prompt.select("Choose type of column:", %w(references boolean string text integer decimal float binary date time datetime primary_key digest token))
85
+
86
+ if column_type == 'references'
87
+ columns_data[:meta][:polymorphic] = true if prompt.select("Polymorphic association?", boolean_choices)
88
+ end
89
+ if %w(integer string text binary).include?(column_type)
90
+ if prompt.select("Set limit?", boolean_choices)
91
+ limit = prompt.ask("Specify limit:", required: true) do |q|
92
+ q.modify :remove
93
+ q.convert(:int, "Invalid input! Please provide integer value.")
94
+ end
95
+ columns_data[:meta][:limit] = limit
96
+ end
97
+ end
98
+ if column_type == 'decimal'
99
+ if prompt.select("Set precision & scale?", boolean_choices)
100
+ precision = prompt.ask("Specify precision:", required: true) do |q|
101
+ q.modify :remove
102
+ q.convert(:int, "Invalid input! Please provide integer value.")
103
+ end
104
+ columns_data[:meta][:precision] = precision
105
+ scale = prompt.ask("Specify scale:", required: true) do |q|
106
+ q.modify :remove
107
+ q.convert(:int, "Invalid input! Please provide integer value.")
108
+ end
109
+ columns_data[:meta][:scale] = scale
110
+ end
111
+ end
112
+
113
+ if %w(references primary_key digest token).exclude?(column_type) && prompt.select("Add default value?", boolean_choices)
114
+ acceptable_value_type = { 'text' => :string }[column_type] || column_type.to_sym
115
+ columns_data[:meta][:default] = prompt.ask("Specify default value:", required: true) do |q|
116
+ q.modify :remove
117
+ q.convert(acceptable_value_type, "Invalid input! Please provide %{type} value.")
118
+ end
119
+ end
120
+
121
+ if prompt.select("Add index?", boolean_choices)
122
+ columns_data[:meta][:index] = prompt.select("Unique index?", boolean_choices) ? :unique : true
123
+ end
124
+
125
+ columns_data.merge!(name: column_name, type: column_type)
126
+ columns << columns_data
127
+ end
128
+ columns
129
+ end
130
+
131
+ def need_timestamps?
132
+ prompt = TTY::Prompt.new
133
+ boolean_choices = [{name: "yes", value: true}, {name: "no", value: false}]
134
+ prompt.select("Add timestamps?", boolean_choices)
135
+ end
136
+
137
+ def content_for_create_table(table_name, columns_data, need_timestamps)
138
+ columns_data_content = columns_data.map do |c|
139
+ column_row = ["t.#{c[:type]} :#{c[:name]}"]
140
+ c[:meta].each { |key, value| column_row << "#{key}: #{value.inspect}" }
141
+ column_row.join(', ')
142
+ end
143
+ columns_data_content << "t.timestamps" if need_timestamps
144
+ <<-CONTENT
145
+ def change
146
+ create_table :#{table_name}#{primary_key_type} do |t|
147
+ #{columns_data_content.join("\n ")}
148
+ end
149
+ end
150
+ CONTENT
151
+ end
152
+
153
+ def content_for_create_join_table(table1_name, table2_name, table_name, columns_data, need_timestamps)
154
+ columns_data_content = columns_data.map do |c|
155
+ column_row = ["t.#{c[:type]} :#{c[:name]}"]
156
+ c[:meta]&.each { |key, value| column_row << "#{key}: #{value.inspect}" }
157
+ column_row.join(', ')
158
+ end
159
+ columns_data_content << "t.timestamps" if need_timestamps
160
+ <<-CONTENT
161
+ def change
162
+ create_join_table :#{table1_name}, :#{table2_name}, table_name: :#{table_name} do |t|
163
+ #{columns_data_content.join("\n ")}
164
+ end
165
+ end
166
+ CONTENT
167
+ end
168
+
169
+ def content_for_drop_table(table_name)
170
+ <<-CONTENT
171
+ def change
172
+ drop_table :#{table_name}
173
+ end
174
+ CONTENT
175
+ end
176
+
177
+ end
178
+ end
@@ -0,0 +1,3 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ <%= @content -%>
3
+ end
@@ -25,6 +25,7 @@ module RailsSteroids
25
25
  puts "| Functionality | Command |"
26
26
  puts "|---|---|"
27
27
  steroid_names = [
28
+ 'migration',
28
29
  'model',
29
30
  'controller',
30
31
  'new_project',
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsSteroids
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_steroids
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anand Bait
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-06 00:00:00.000000000 Z
11
+ date: 2024-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -106,6 +106,9 @@ files:
106
106
  - bin/setup
107
107
  - lib/generators/steroid/controller/USAGE
108
108
  - lib/generators/steroid/controller/controller_generator.rb
109
+ - lib/generators/steroid/migration/USAGE
110
+ - lib/generators/steroid/migration/migration_generator.rb
111
+ - lib/generators/steroid/migration/templates/migration.rb.tt
109
112
  - lib/generators/steroid/model/USAGE
110
113
  - lib/generators/steroid/model/model_generator.rb
111
114
  - lib/generators/steroid/new_project/USAGE