Skip to content
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

Extract #build_add_column_definition #45643

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def visit_AlterTable(o)
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
sql << o.check_constraint_adds.map { |con| visit_AddCheckConstraint con }.join(" ")
sql << o.check_constraint_drops.map { |con| visit_DropCheckConstraint con }.join(" ")
o.ddl = sql
end

def visit_ColumnDefinition(o)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ class AlterTable # :nodoc:
attr_reader :adds
attr_reader :foreign_key_adds, :foreign_key_drops
attr_reader :check_constraint_adds, :check_constraint_drops
attr_accessor :ddl

def initialize(td)
@td = td
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,24 @@ def drop_table(table_name, **options)
# # Ignores the method call if the column exists
# add_column(:shapes, :triangle, 'polygon', if_not_exists: true)
def add_column(table_name, column_name, type, **options)
add_column_def = build_add_column_definition(table_name, column_name, type, **options)
return unless add_column_def

execute(add_column_def.ddl)
end

def add_columns(table_name, *column_names, type:, **options) # :nodoc:
column_names.each do |column_name|
add_column(table_name, column_name, type, **options)
end
end

# Builds an AlterTable object for adding a column to a table.
#
# This definition object contains information about the column that would be created
# if the same arguments were passed to #add_column. See #add_column for information about
# passing a +table_name+, +column_name+, +type+ and other options that can be passed.
def build_add_column_definition(table_name, column_name, type, **options) # :nodoc:
return if options[:if_not_exists] == true && column_exists?(table_name, column_name)

if supports_datetime_with_precision?
Expand All @@ -607,15 +625,10 @@ def add_column(table_name, column_name, type, **options)
end
end

at = create_alter_table table_name
at.add_column(column_name, type, **options)
execute schema_creation.accept at
end

def add_columns(table_name, *column_names, type:, **options) # :nodoc:
column_names.each do |column_name|
add_column(table_name, column_name, type, **options)
end
alter_table = create_alter_table(table_name)
alter_table.add_column(column_name, type, **options)
schema_creation.accept(alter_table)
alter_table
end

# Removes the given columns from the table definition.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def visit_AlterTable(o)
sql << o.constraint_validations.map { |fk| visit_ValidateConstraint fk }.join(" ")
sql << o.exclusion_constraint_adds.map { |con| visit_AddExclusionConstraint con }.join(" ")
sql << o.exclusion_constraint_drops.map { |con| visit_DropExclusionConstraint con }.join(" ")
o.ddl = sql
end

def visit_AddForeignKey(o)
Expand Down
17 changes: 17 additions & 0 deletions activerecord/test/cases/migration/schema_definitions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,23 @@ def test_build_create_index_definition_for_existing_index
connection.drop_table(:test) if connection.table_exists?(:test)
end
end

def test_build_add_column_definition
connection.create_table(:test)
add_col_td = connection.build_add_column_definition(:test, :foo, :string)

assert_match "ALTER TABLE", add_col_td.ddl

add_cols = add_col_td.adds
assert_equal 1, add_cols.size

add_col = add_cols.first.column
assert_equal "foo", add_col.name
assert add_col.type
assert add_col.sql_type
ensure
connection.drop_table(:test) if connection.table_exists?(:test)
end
end
end
end