aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYves Senn <yves.senn@gmail.com>2014-06-10 11:50:37 +0200
committerYves Senn <yves.senn@gmail.com>2014-06-26 22:03:48 +0200
commit1c170fdea2be04691c7daa8266084766fe963fff (patch)
treeb0735d6f12d2f8b744f9eb6cac664c388a9d4d50
parent74b2fe4c0febe051cb48c7c25a565333ddf22bce (diff)
downloadrails-1c170fdea2be04691c7daa8266084766fe963fff.tar.gz
rails-1c170fdea2be04691c7daa8266084766fe963fff.tar.bz2
rails-1c170fdea2be04691c7daa8266084766fe963fff.zip
fk: generalize using `AlterTable` and `SchemaCreation`.
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb37
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb24
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb20
-rw-r--r--activerecord/test/cases/migration/foreign_key_test.rb6
6 files changed, 64 insertions, 49 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb
index 47fe501752..ad62eab4d2 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb
@@ -18,11 +18,25 @@ module ActiveRecord
add_column_options!(sql, column_options(o))
end
+ def visit_AddForeignKey(o)
+ <<-SQL
+ADD CONSTRAINT #{quote_column_name(o.name)}
+FOREIGN KEY (#{quote_column_name(o.column)})
+ REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
+ SQL
+ end
+
+ def visit_DropForeignKey(name)
+ "DROP CONSTRAINT #{name}"
+ end
+
private
def visit_AlterTable(o)
sql = "ALTER TABLE #{quote_table_name(o.name)} "
sql << o.adds.map { |col| visit_AddColumn col }.join(' ')
+ sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(' ')
+ sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(' ')
end
def visit_ColumnDefinition(o)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index b132543332..c18ebf1014 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -317,14 +317,26 @@ module ActiveRecord
class AlterTable # :nodoc:
attr_reader :adds
+ attr_reader :foreign_key_adds
+ attr_reader :foreign_key_drops
def initialize(td)
@td = td
@adds = []
+ @foreign_key_adds = []
+ @foreign_key_drops = []
end
def name; @td.name; end
+ def add_foreign_key(to_table, options)
+ @foreign_key_adds << ForeignKeyDefinition.new(name, to_table, options)
+ end
+
+ def drop_foreign_key(name)
+ @foreign_key_drops << name
+ end
+
def add_column(name, type, options)
name = name.to_s
type = type.to_sym
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 55e3fb4477..da6b15dad0 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -625,13 +625,6 @@ module ActiveRecord
end
alias :add_belongs_to :add_reference
- def foreign_key_name(table_name, options)
- options.fetch(:name) do
- column_name = options.fetch(:column)
- "#{table_name}_#{column_name}_fk"
- end
- end
-
# Removes the reference(s). Also removes a +type+ column if one exists.
# <tt>remove_reference</tt>, <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
#
@@ -649,6 +642,36 @@ module ActiveRecord
end
alias :remove_belongs_to :remove_reference
+ def foreign_keys(table_name)
+ raise NotImplementedError, "foreign_keys is not implemented"
+ end
+
+ def add_foreign_key(from_table, to_table, options = {})
+ options = {
+ column: options.fetch(:column),
+ primary_key: "id",
+ name: foreign_key_name(from_table, options)
+ }
+ at = create_alter_table from_table
+ at.add_foreign_key to_table, options
+
+ execute schema_creation.accept at
+ end
+
+ def remove_foreign_key(from_table, options = {})
+ at = create_alter_table from_table
+ at.drop_foreign_key foreign_key_name(from_table, options)
+
+ execute schema_creation.accept at
+ end
+
+ def foreign_key_name(table_name, options) # :nodoc:
+ options.fetch(:name) do
+ column_name = options.fetch(:column)
+ "#{table_name}_#{column_name}_fk"
+ end
+ end
+
def dump_schema_information #:nodoc:
sm_table = ActiveRecord::Migrator.schema_migrations_table_name
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 431db591e6..6ba226765c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -10,6 +10,10 @@ module ActiveRecord
add_column_position!(super, column_options(o))
end
+ def visit_DropForeignKey(name)
+ "DROP FOREIGN KEY #{name}"
+ end
+
private
def visit_TableDefinition(o)
@@ -525,26 +529,6 @@ module ActiveRecord
end
end
- def add_foreign_key(from_table, to_table, options = {})
- foreign_key_column = options.fetch(:column)
- referenced_column = "id"
- foreign_key_name = foreign_key_name(from_table, options)
- execute <<-SQL
-ALTER TABLE #{quote_table_name(from_table)}
-ADD CONSTRAINT #{foreign_key_name}
-FOREIGN KEY (#{quote_column_name(foreign_key_column)})
-REFERENCES #{quote_table_name(to_table)} (#{quote_column_name(referenced_column)})
- SQL
- end
-
- def remove_foreign_key(from_table, options = {})
- foreign_key_name = foreign_key_name(from_table, options)
- execute <<-SQL
-ALTER TABLE #{quote_table_name(from_table)}
-DROP FOREIGN KEY #{foreign_key_name}
- SQL
- end
-
# Maps logical Rails types to MySQL-specific data types.
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
case type.to_s
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 7a93d9cde7..c061337e71 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -472,26 +472,6 @@ ORDER BY c.conname
end
end
- def add_foreign_key(from_table, to_table, options = {})
- foreign_key_column = options.fetch(:column)
- referenced_column = "id"
- foreign_key_name = foreign_key_name(from_table, options)
- execute <<-SQL
-ALTER TABLE #{quote_table_name(from_table)}
-ADD CONSTRAINT #{foreign_key_name}
- FOREIGN KEY (#{quote_column_name(foreign_key_column)})
- REFERENCES #{quote_table_name(to_table)} (#{quote_column_name(referenced_column)})
- SQL
- end
-
- def remove_foreign_key(from_table, options = {})
- foreign_key_name = foreign_key_name(from_table, options)
- execute <<-SQL
-ALTER TABLE #{quote_table_name(from_table)}
-DROP CONSTRAINT #{foreign_key_name}
- SQL
- end
-
def index_name_length
63
end
diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb
index 655393445d..6ad595668f 100644
--- a/activerecord/test/cases/migration/foreign_key_test.rb
+++ b/activerecord/test/cases/migration/foreign_key_test.rb
@@ -23,8 +23,10 @@ module ActiveRecord
end
teardown do
- @connection.execute "DROP TABLE IF EXISTS astronauts"
- @connection.execute "DROP TABLE IF EXISTS rockets"
+ if defined?(@connection)
+ @connection.execute "DROP TABLE IF EXISTS astronauts"
+ @connection.execute "DROP TABLE IF EXISTS rockets"
+ end
end
def test_foreign_keys