aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2018-08-20 02:15:18 +0900
committerRyuta Kamizono <kamipo@gmail.com>2018-08-20 02:27:14 +0900
commitb6e583343ab0ce117b7358d09cd5fe5d1854f8a2 (patch)
tree086be3bad342666877d96d8182491f5ad797366b /activerecord
parentfd1ec91c73ccfa1df71098a93cee76e9dd12a24b (diff)
downloadrails-b6e583343ab0ce117b7358d09cd5fe5d1854f8a2.tar.gz
rails-b6e583343ab0ce117b7358d09cd5fe5d1854f8a2.tar.bz2
rails-b6e583343ab0ce117b7358d09cd5fe5d1854f8a2.zip
SQLite3: Fix rename reference column not to lose foreign key constraint
Fixes #33520.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb26
-rw-r--r--activerecord/test/cases/migration/foreign_key_test.rb16
2 files changed, 31 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 38b1c31376..c61e94f159 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -409,14 +409,24 @@ module ActiveRecord
def alter_table(table_name, options = {})
altered_table_name = "a#{table_name}"
- options_to_restore = { foreign_keys: foreign_keys(table_name) }
- caller = lambda { |definition| yield definition if block_given? }
+ foreign_keys = foreign_keys(table_name)
+
+ caller = lambda do |definition|
+ rename = options[:rename] || {}
+ foreign_keys.each do |fk|
+ if column = rename[fk.options[:column]]
+ fk.options[:column] = column
+ end
+ definition.foreign_key(fk.to_table, fk.options)
+ end
+
+ yield definition if block_given?
+ end
transaction do
disable_referential_integrity do
- move_table(table_name, altered_table_name,
- options.merge(temporary: true))
- move_table(altered_table_name, table_name, options_to_restore, &caller)
+ move_table(table_name, altered_table_name, options.merge(temporary: true))
+ move_table(altered_table_name, table_name, &caller)
end
end
end
@@ -448,12 +458,6 @@ module ActiveRecord
)
end
- if options[:foreign_keys]
- options[:foreign_keys].each do |fk|
- @definition.foreign_key(fk.to_table, fk.options)
- end
- end
-
yield @definition if block_given?
end
copy_table_indexes(from, to, options[:rename] || {})
diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb
index 4b4cdf141e..bb233fbf74 100644
--- a/activerecord/test/cases/migration/foreign_key_test.rb
+++ b/activerecord/test/cases/migration/foreign_key_test.rb
@@ -81,6 +81,22 @@ if ActiveRecord::Base.connection.supports_foreign_keys_in_create?
assert_equal "astronauts", fk.from_table
assert_equal "rockets", fk.to_table
end
+
+ def test_rename_reference_column_of_child_table
+ rocket = Rocket.create!(name: "myrocket")
+ rocket.astronauts << Astronaut.create!
+
+ @connection.rename_column :astronauts, :rocket_id, :new_rocket_id
+
+ foreign_keys = @connection.foreign_keys("astronauts")
+ assert_equal 1, foreign_keys.size
+
+ fk = foreign_keys.first
+ assert_equal "myrocket", Rocket.first.name
+ assert_equal "astronauts", fk.from_table
+ assert_equal "rockets", fk.to_table
+ assert_equal "new_rocket_id", fk.options[:column]
+ end
end
end
end