Class: SlashMigrate::Column
- Inherits:
-
Object
- Object
- SlashMigrate::Column
- Defined in:
- app/services/slash_migrate/column.rb
Overview
A single column in a migration plan. Renders itself as the ‘t.<type> :name` line for a create_table block, including the options Rails’ generator grammar can’t express (null:, default:). Shared by the new-model flow and, later, the modify-table flow.
Constant Summary collapse
- TYPES =
%w[ string text integer bigint float decimal boolean date datetime time references binary json ].freeze
- REFERENCE_TYPES =
%w[references belongs_to].freeze
- INDEX_CHOICES =
%w[index uniq].freeze
Instance Attribute Summary collapse
-
#default ⇒ Object
readonly
Returns the value of attribute default.
-
#index ⇒ Object
readonly
Returns the value of attribute index.
-
#limit ⇒ Object
readonly
Returns the value of attribute limit.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#precision ⇒ Object
readonly
Returns the value of attribute precision.
-
#scale ⇒ Object
readonly
Returns the value of attribute scale.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Class Method Summary collapse
- .from_params(row) ⇒ Object
-
.from_schema(ar_column) ⇒ Object
Builds a Column from an Active Record column (the live schema), so the engine can reconstruct a column’s current definition — needed to make a drop reversible and to pre-fill the edit form.
Instance Method Summary collapse
-
#add_statement(table_name) ⇒ Object
The standalone statement that adds this column to an existing table, reusing the same option rendering as the create_table line.
- #allow_null? ⇒ Boolean
- #belongs_to_line ⇒ Object
- #blank? ⇒ Boolean
-
#default_sql ⇒ Object
The default rendered as a Ruby literal (or “nil”), for change_column_default’s from:/to: arguments.
-
#foreign_key? ⇒ Boolean
A references column gets a foreign key only when it’s pointed at a real target table; with no target it’s just the _id column (plus its index), which always migrates cleanly even if no such table exists yet.
- #index_statement(table_name) ⇒ Object
-
#indexed? ⇒ Boolean
References are indexed inline by Rails, so they never get a separate add_index line.
-
#initialize(name:, type: "string", null: true, default: nil, limit: nil, precision: nil, scale: nil, index: "", to_table: nil) ⇒ Column
constructor
A new instance of Column.
- #reference? ⇒ Boolean
-
#remove_statement(table_name) ⇒ Object
remove_column is only reversible when given the column’s type; we also pass the other options so a rollback recreates the column faithfully.
-
#to_ruby ⇒ Object
The line that goes inside ‘create_table do |t|`.
- #unique_index? ⇒ Boolean
Constructor Details
#initialize(name:, type: "string", null: true, default: nil, limit: nil, precision: nil, scale: nil, index: "", to_table: nil) ⇒ Column
Returns a new instance of Column.
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'app/services/slash_migrate/column.rb', line 49 def initialize(name:, type: "string", null: true, default: nil, limit: nil, precision: nil, scale: nil, index: "", to_table: nil) @name = name.to_s.strip @type = type.to_s @null = null @default = presence(default) @limit = presence(limit) @precision = presence(precision) @scale = presence(scale) @index = index.to_s @to_table = presence(to_table) end |
Instance Attribute Details
#default ⇒ Object (readonly)
Returns the value of attribute default.
47 48 49 |
# File 'app/services/slash_migrate/column.rb', line 47 def default @default end |
#index ⇒ Object (readonly)
Returns the value of attribute index.
47 48 49 |
# File 'app/services/slash_migrate/column.rb', line 47 def index @index end |
#limit ⇒ Object (readonly)
Returns the value of attribute limit.
47 48 49 |
# File 'app/services/slash_migrate/column.rb', line 47 def limit @limit end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
47 48 49 |
# File 'app/services/slash_migrate/column.rb', line 47 def name @name end |
#precision ⇒ Object (readonly)
Returns the value of attribute precision.
47 48 49 |
# File 'app/services/slash_migrate/column.rb', line 47 def precision @precision end |
#scale ⇒ Object (readonly)
Returns the value of attribute scale.
47 48 49 |
# File 'app/services/slash_migrate/column.rb', line 47 def scale @scale end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
47 48 49 |
# File 'app/services/slash_migrate/column.rb', line 47 def type @type end |
Class Method Details
.from_params(row) ⇒ Object
14 15 16 17 18 19 20 21 22 23 |
# File 'app/services/slash_migrate/column.rb', line 14 def self.from_params(row) new( name: row[:name], type: row[:type], null: row[:null].to_s != "not_null", default: row[:default], index: row[:index], to_table: row[:to_table] ) end |
.from_schema(ar_column) ⇒ Object
Builds a Column from an Active Record column (the live schema), so the engine can reconstruct a column’s current definition — needed to make a drop reversible and to pre-fill the edit form.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'app/services/slash_migrate/column.rb', line 28 def self.from_schema(ar_column) = ar_column. new( name: ar_column.name, type: ar_column.type.to_s, null: ar_column.null, # Normalize to a String, matching the form-input path. Active Record # casts defaults differently across versions and adapters (Rails 8.0 # hands back "0", 8.1 casts it to 0; a boolean default arrives as # false), and the rest of this class — presence, downcase, literal # interpolation — assumes a string. Without &.to_s, presence(false) # would also silently drop a boolean's `default: false`. default: ar_column.default&.to_s, limit: &.limit, precision: &.precision, scale: &.scale ) end |
Instance Method Details
#add_statement(table_name) ⇒ Object
The standalone statement that adds this column to an existing table, reusing the same option rendering as the create_table line.
104 105 106 107 108 109 110 111 112 113 114 |
# File 'app/services/slash_migrate/column.rb', line 104 def add_statement(table_name) if reference? = statement = "add_reference :#{table_name}, :#{name}" else = statement = "add_column :#{table_name}, :#{name}, :#{type}" end statement += ", #{.join(", ")}" unless .empty? statement end |
#allow_null? ⇒ Boolean
70 71 72 |
# File 'app/services/slash_migrate/column.rb', line 70 def allow_null? @null end |
#belongs_to_line ⇒ Object
130 131 132 133 134 135 |
# File 'app/services/slash_migrate/column.rb', line 130 def belongs_to_line = [] << "class_name: #{@to_table.classify.inspect}" if foreign_key? && !conventional_reference? << requiredness_option if requiredness_option .empty? ? "belongs_to :#{name}" : "belongs_to :#{name}, #{.join(", ")}" end |
#blank? ⇒ Boolean
62 63 64 |
# File 'app/services/slash_migrate/column.rb', line 62 def blank? name.empty? end |
#default_sql ⇒ Object
The default rendered as a Ruby literal (or “nil”), for change_column_default’s from:/to: arguments.
126 127 128 |
# File 'app/services/slash_migrate/column.rb', line 126 def default_sql @default.nil? ? "nil" : rendered_default end |
#foreign_key? ⇒ Boolean
A references column gets a foreign key only when it’s pointed at a real target table; with no target it’s just the _id column (plus its index), which always migrates cleanly even if no such table exists yet.
77 78 79 |
# File 'app/services/slash_migrate/column.rb', line 77 def foreign_key? !@to_table.nil? end |
#index_statement(table_name) ⇒ Object
96 97 98 99 100 |
# File 'app/services/slash_migrate/column.rb', line 96 def index_statement(table_name) statement = "add_index :#{table_name}, :#{name}" statement += ", unique: true" if unique_index? statement end |
#indexed? ⇒ Boolean
References are indexed inline by Rails, so they never get a separate add_index line.
83 84 85 |
# File 'app/services/slash_migrate/column.rb', line 83 def indexed? !reference? && INDEX_CHOICES.include?(index) end |
#reference? ⇒ Boolean
66 67 68 |
# File 'app/services/slash_migrate/column.rb', line 66 def reference? REFERENCE_TYPES.include?(type) end |
#remove_statement(table_name) ⇒ Object
remove_column is only reversible when given the column’s type; we also pass the other options so a rollback recreates the column faithfully.
118 119 120 121 122 |
# File 'app/services/slash_migrate/column.rb', line 118 def remove_statement(table_name) statement = "remove_column :#{table_name}, :#{name}, :#{type}" statement += ", #{.join(", ")}" unless .empty? statement end |
#to_ruby ⇒ Object
The line that goes inside ‘create_table do |t|`.
92 93 94 |
# File 'app/services/slash_migrate/column.rb', line 92 def to_ruby "t.#{type} :#{name}#{}" end |
#unique_index? ⇒ Boolean
87 88 89 |
# File 'app/services/slash_migrate/column.rb', line 87 def unique_index? index == "uniq" end |