aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAster Ryan <astersamazing@gmail.com>2015-05-20 10:05:51 -0400
committerAster Ryan <astersamazing@gmail.com>2015-06-11 19:24:46 -0400
commita186663b3d274b7aa648683f3fdf7a816fe90763 (patch)
tree0312dff8c6a3f0563809cfb57004511c09af4114 /activerecord
parente2dfa54db881fceae92bdf793d5545c3f0e22898 (diff)
downloadrails-a186663b3d274b7aa648683f3fdf7a816fe90763.tar.gz
rails-a186663b3d274b7aa648683f3fdf7a816fe90763.tar.bz2
rails-a186663b3d274b7aa648683f3fdf7a816fe90763.zip
Add an invert method for remove_foreign_key
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md5
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb7
-rw-r--r--activerecord/lib/active_record/migration/command_recorder.rb10
-rw-r--r--activerecord/test/cases/migration/command_recorder_test.rb31
4 files changed, 51 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 6680ef4bd2..76d65e41de 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Make remove_foreign_key invertible. Any foreign key options must be
+ specified, similar to remove_column.
+
+ *Aster Ryan*
+
* Correctly handle decimal arrays with defaults in the schema dumper.
Fixes #20515.
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 dd7dcb9cdd..a89886721a 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -777,7 +777,10 @@ module ActiveRecord
execute schema_creation.accept(at)
end
- # Removes the given foreign key from the table.
+ # Removes the given foreign key from the table. Any options parameters provided
+ # will be used to re-add the foreign key in case of a migration reversion.
+ # It is recommended that you provide any options used when creating the foreign
+ # key so that the migration can be reverted properly.
#
# Removes the foreign key on +accounts.branch_id+.
#
@@ -791,6 +794,8 @@ module ActiveRecord
#
# remove_foreign_key :accounts, name: :special_fk_name
#
+ # The +options+ hash can include all keys that can be used in add_foreign_key.
+ # Please refer to the add_foreign_key documentation for a full list
def remove_foreign_key(from_table, options_or_to_table = {})
return unless supports_foreign_keys?
diff --git a/activerecord/lib/active_record/migration/command_recorder.rb b/activerecord/lib/active_record/migration/command_recorder.rb
index 36256415df..ee4545ed71 100644
--- a/activerecord/lib/active_record/migration/command_recorder.rb
+++ b/activerecord/lib/active_record/migration/command_recorder.rb
@@ -184,6 +184,16 @@ module ActiveRecord
[:remove_foreign_key, [from_table, options]]
end
+ def invert_remove_foreign_key(args)
+ from_table, to_table, remove_options = args
+ raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil? || to_table.is_a?(Hash)
+
+ reversed_args = [from_table, to_table]
+ reversed_args << remove_options if remove_options
+
+ [:add_foreign_key, reversed_args]
+ end
+
# Forwards any missing method call to the \target.
def method_missing(method, *args, &block)
if @delegate.respond_to?(method)
diff --git a/activerecord/test/cases/migration/command_recorder_test.rb b/activerecord/test/cases/migration/command_recorder_test.rb
index 3844b1a92e..24d3c085a7 100644
--- a/activerecord/test/cases/migration/command_recorder_test.rb
+++ b/activerecord/test/cases/migration/command_recorder_test.rb
@@ -281,17 +281,42 @@ module ActiveRecord
assert_equal [:remove_foreign_key, [:dogs, :people]], enable
end
+ def test_invert_remove_foreign_key
+ enable = @recorder.inverse_of :remove_foreign_key, [:dogs, :people]
+ assert_equal [:add_foreign_key, [:dogs, :people]], enable
+ end
+
def test_invert_add_foreign_key_with_column
enable = @recorder.inverse_of :add_foreign_key, [:dogs, :people, column: "owner_id"]
assert_equal [:remove_foreign_key, [:dogs, column: "owner_id"]], enable
end
+ def test_invert_remove_foreign_key_with_column
+ enable = @recorder.inverse_of :remove_foreign_key, [:dogs, :people, column: "owner_id"]
+ assert_equal [:add_foreign_key, [:dogs, :people, column: "owner_id"]], enable
+ end
+
def test_invert_add_foreign_key_with_column_and_name
enable = @recorder.inverse_of :add_foreign_key, [:dogs, :people, column: "owner_id", name: "fk"]
assert_equal [:remove_foreign_key, [:dogs, name: "fk"]], enable
end
- def test_remove_foreign_key_is_irreversible
+ def test_invert_remove_foreign_key_with_column_and_name
+ enable = @recorder.inverse_of :remove_foreign_key, [:dogs, :people, column: "owner_id", name: "fk"]
+ assert_equal [:add_foreign_key, [:dogs, :people, column: "owner_id", name: "fk"]], enable
+ end
+
+ def test_invert_remove_foreign_key_with_primary_key
+ enable = @recorder.inverse_of :remove_foreign_key, [:dogs, :people, primary_key: "person_id"]
+ assert_equal [:add_foreign_key, [:dogs, :people, primary_key: "person_id"]], enable
+ end
+
+ def test_invert_remove_foreign_key_with_on_delete_on_update
+ enable = @recorder.inverse_of :remove_foreign_key, [:dogs, :people, on_delete: :nullify, on_update: :cascade]
+ assert_equal [:add_foreign_key, [:dogs, :people, on_delete: :nullify, on_update: :cascade]], enable
+ end
+
+ def test_invert_remove_foreign_key_is_irreversible_without_to_table
assert_raises ActiveRecord::IrreversibleMigration do
@recorder.inverse_of :remove_foreign_key, [:dogs, column: "owner_id"]
end
@@ -299,6 +324,10 @@ module ActiveRecord
assert_raises ActiveRecord::IrreversibleMigration do
@recorder.inverse_of :remove_foreign_key, [:dogs, name: "fk"]
end
+
+ assert_raises ActiveRecord::IrreversibleMigration do
+ @recorder.inverse_of :remove_foreign_key, [:dogs]
+ end
end
end
end