diff options
author | Yves Senn <yves.senn@gmail.com> | 2015-02-11 11:09:29 +0100 |
---|---|---|
committer | Yves Senn <yves.senn@gmail.com> | 2015-02-11 11:20:59 +0100 |
commit | a893718c3165aa6ef6b2b500f7922954ba21eb02 (patch) | |
tree | cbc8692b54f5b6f72040000bfd6bf78d16b5bf9a /activerecord | |
parent | 9bdb083dba0778f47866fa440476b3141716de52 (diff) | |
download | rails-a893718c3165aa6ef6b2b500f7922954ba21eb02.tar.gz rails-a893718c3165aa6ef6b2b500f7922954ba21eb02.tar.bz2 rails-a893718c3165aa6ef6b2b500f7922954ba21eb02.zip |
fix `remove_reference` with `foreign_key: true` on MySQL. #18664.
MySQL rejects to remove an index which is used in a foreign key constraint:
```
ActiveRecord::StatementInvalid: Mysql2::Error: Cannot drop index 'index_copies_on_title_id': needed in a foreign key constraint: ALTER TABLE `copies` DROP `title_id`
```
Removing the constraint before removing the column (and the index) solves this problem.
Diffstat (limited to 'activerecord')
3 files changed, 24 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index c1b803c7f8..064c9008e0 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,11 @@ +* `remove_reference` with `foreign_key: true` removes the foreign key before + removing the column. This fixes a bug where it was not possible to remove + the column on MySQL. + + Fixes #18664. + + *Yves Senn* + * `find_in_batches` now accepts an `:end_at` parameter that complements the `:start` parameter to specify where to stop batch processing. diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index ed32997d25..3ca1c3c49a 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -662,7 +662,13 @@ module ActiveRecord # # remove_reference(:products, :supplier, polymorphic: true) # + # ====== Remove the reference with a foreign key + # + # remove_reference(:products, :user, index: true, foreign_key: true) + # def remove_reference(table_name, ref_name, options = {}) + remove_foreign_key table_name, ref_name if options[:foreign_key] + remove_column(table_name, "#{ref_name}_id") remove_column(table_name, "#{ref_name}_type") if options[:polymorphic] end diff --git a/activerecord/test/cases/migration/references_foreign_key_test.rb b/activerecord/test/cases/migration/references_foreign_key_test.rb index 99de7db70c..cf1328e4d0 100644 --- a/activerecord/test/cases/migration/references_foreign_key_test.rb +++ b/activerecord/test/cases/migration/references_foreign_key_test.rb @@ -95,6 +95,16 @@ module ActiveRecord end end end + + test "foreign key column can be removed" do + @connection.create_table :testings do |t| + t.references :testing_parent, index: true, foreign_key: true + end + + assert_difference "@connection.foreign_keys('testings').size", -1 do + @connection.remove_reference :testings, :testing_parent, foreign_key: true + end + end end end end |