Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fk: make `add_foreign_key` reversible.

  • Loading branch information...
commit 6073d7c683b19fc7394baa9a93bc44e71e071129 1 parent 402f303
@senny senny authored
View
17 activerecord/lib/active_record/migration/command_recorder.rb
@@ -74,7 +74,9 @@ def respond_to?(*args) # :nodoc:
:rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
:change_column_default, :add_reference, :remove_reference, :transaction,
:drop_join_table, :drop_table, :execute_block, :enable_extension,
- :change_column, :execute, :remove_columns, :change_column_null # irreversible methods need to be here too
+ :change_column, :execute, :remove_columns, :change_column_null,
+ :add_foreign_key, :remove_foreign_key
+ # irreversible methods need to be here too
].each do |method|
class_eval <<-EOV, __FILE__, __LINE__ + 1
def #{method}(*args, &block) # def create_table(*args, &block)
@@ -167,6 +169,19 @@ def invert_change_column_null(args)
[:change_column_null, args]
end
+ def invert_add_foreign_key(args)
+ from_table, _to_table, add_options = *args
+ add_options ||= {}
+
+ if add_options[:name]
+ options = {name: add_options[:name]}
+ elsif add_options[:column]
+ options = {column: add_options[:column]}
+ end
+
+ [:remove_foreign_key, [from_table, options]]
+ end
+
# Forwards any missing method call to the \target.
def method_missing(method, *args, &block)
if @delegate.respond_to?(method)
View
20 activerecord/test/cases/migration/command_recorder_test.rb
@@ -270,6 +270,26 @@ def test_invert_disable_extension
enable = @recorder.inverse_of :disable_extension, ['uuid-ossp']
assert_equal [:enable_extension, ['uuid-ossp'], nil], 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_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
+ assert_raises ActiveRecord::IrreversibleMigration do
+ @recorder.inverse_of :remove_foreign_key, [:dogs, column: "owner_id"]
+ end
+
+ assert_raises ActiveRecord::IrreversibleMigration do
+ @recorder.inverse_of :remove_foreign_key, [:dogs, name: "fk"]
+ end
+ end
end
end
end
View
19 activerecord/test/cases/migration/foreign_key_test.rb
@@ -139,6 +139,25 @@ def test_schema_dumping_dependent_option
output = dump_table_schema "astronauts"
assert_match %r{\s+add_foreign_key "astronauts",.+dependent: :nullify$}, output
end
+
+ class CreateCitiesAndHousesMigration < ActiveRecord::Migration
+ def change
+ create_table("cities") { |t| }
+
+ create_table("houses") do |t|
+ t.column :city_id, :integer
+ end
+ add_foreign_key :houses, :cities, column: "city_id"
+ end
+ end
+
+ def test_add_foreign_key_is_reversible
+ migration = CreateCitiesAndHousesMigration.new
+ silence_stream($stdout) { migration.migrate(:up) }
+ assert_equal ["houses_city_id_fk"], @connection.foreign_keys("houses").map(&:name)
+ ensure
+ silence_stream($stdout) { migration.migrate(:down) }
+ end
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.