mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
fk: infere column name from table names.
This allows to create and remove foreign keys without specifying a column.
This commit is contained in:
parent
6073d7c683
commit
d074b82148
4 changed files with 46 additions and 7 deletions
|
@ -647,10 +647,11 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_foreign_key(from_table, to_table, options = {})
|
def add_foreign_key(from_table, to_table, options = {})
|
||||||
|
options[:column] ||= foreign_key_column_for(to_table)
|
||||||
primary_key = options.fetch(:primary_key, "id")
|
primary_key = options.fetch(:primary_key, "id")
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
column: options.fetch(:column),
|
column: options[:column],
|
||||||
primary_key: primary_key,
|
primary_key: primary_key,
|
||||||
name: foreign_key_name(from_table, options),
|
name: foreign_key_name(from_table, options),
|
||||||
dependent: options.fetch(:dependent, nil)
|
dependent: options.fetch(:dependent, nil)
|
||||||
|
@ -661,17 +662,26 @@ module ActiveRecord
|
||||||
execute schema_creation.accept at
|
execute schema_creation.accept at
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_foreign_key(from_table, options = {})
|
def remove_foreign_key(from_table, options_or_to_table = {})
|
||||||
|
if options_or_to_table.is_a?(Hash)
|
||||||
|
options = options_or_to_table
|
||||||
|
else
|
||||||
|
options = { column: foreign_key_column_for(options_or_to_table) }
|
||||||
|
end
|
||||||
|
|
||||||
at = create_alter_table from_table
|
at = create_alter_table from_table
|
||||||
at.drop_foreign_key foreign_key_name(from_table, options)
|
at.drop_foreign_key foreign_key_name(from_table, options)
|
||||||
|
|
||||||
execute schema_creation.accept at
|
execute schema_creation.accept at
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def foreign_key_column_for(table_name) # :nodoc:
|
||||||
|
"#{table_name.to_s.singularize}_id"
|
||||||
|
end
|
||||||
|
|
||||||
def foreign_key_name(table_name, options) # :nodoc:
|
def foreign_key_name(table_name, options) # :nodoc:
|
||||||
options.fetch(:name) do
|
options.fetch(:name) do
|
||||||
column_name = options.fetch(:column)
|
"#{table_name}_#{options.fetch(:column)}_fk"
|
||||||
"#{table_name}_#{column_name}_fk"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -170,13 +170,15 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def invert_add_foreign_key(args)
|
def invert_add_foreign_key(args)
|
||||||
from_table, _to_table, add_options = *args
|
from_table, to_table, add_options = *args
|
||||||
add_options ||= {}
|
add_options ||= {}
|
||||||
|
|
||||||
if add_options[:name]
|
if add_options[:name]
|
||||||
options = {name: add_options[:name]}
|
options = {name: add_options[:name]}
|
||||||
elsif add_options[:column]
|
elsif add_options[:column]
|
||||||
options = {column: add_options[:column]}
|
options = {column: add_options[:column]}
|
||||||
|
else
|
||||||
|
options = to_table
|
||||||
end
|
end
|
||||||
|
|
||||||
[:remove_foreign_key, [from_table, options]]
|
[:remove_foreign_key, [from_table, options]]
|
||||||
|
|
|
@ -271,6 +271,11 @@ module ActiveRecord
|
||||||
assert_equal [:enable_extension, ['uuid-ossp'], nil], enable
|
assert_equal [:enable_extension, ['uuid-ossp'], nil], enable
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_invert_add_foreign_key
|
||||||
|
enable = @recorder.inverse_of :add_foreign_key, [:dogs, :people]
|
||||||
|
assert_equal [:remove_foreign_key, [:dogs, :people]], enable
|
||||||
|
end
|
||||||
|
|
||||||
def test_invert_add_foreign_key_with_column
|
def test_invert_add_foreign_key_with_column
|
||||||
enable = @recorder.inverse_of :add_foreign_key, [:dogs, :people, column: "owner_id"]
|
enable = @recorder.inverse_of :add_foreign_key, [:dogs, :people, column: "owner_id"]
|
||||||
assert_equal [:remove_foreign_key, [:dogs, column: "owner_id"]], enable
|
assert_equal [:remove_foreign_key, [:dogs, column: "owner_id"]], enable
|
||||||
|
|
|
@ -46,7 +46,21 @@ module ActiveRecord
|
||||||
assert_equal "fk_name", fk.name
|
assert_equal "fk_name", fk.name
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_add_foreign_key
|
def test_add_foreign_key_inferes_column
|
||||||
|
@connection.add_foreign_key :astronauts, :rockets
|
||||||
|
|
||||||
|
foreign_keys = @connection.foreign_keys("astronauts")
|
||||||
|
assert_equal 1, foreign_keys.size
|
||||||
|
|
||||||
|
fk = foreign_keys.first
|
||||||
|
assert_equal "astronauts", fk.from_table
|
||||||
|
assert_equal "rockets", fk.to_table
|
||||||
|
assert_equal "rocket_id", fk.column
|
||||||
|
assert_equal "id", fk.primary_key
|
||||||
|
assert_equal "astronauts_rocket_id_fk", fk.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_add_foreign_key_with_column
|
||||||
@connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
|
@connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
|
||||||
|
|
||||||
foreign_keys = @connection.foreign_keys("astronauts")
|
foreign_keys = @connection.foreign_keys("astronauts")
|
||||||
|
@ -112,7 +126,15 @@ module ActiveRecord
|
||||||
assert_equal :nullify, fk.dependent
|
assert_equal :nullify, fk.dependent
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_remove_foreign_key
|
def test_remove_foreign_key_inferes_column
|
||||||
|
@connection.add_foreign_key :astronauts, :rockets
|
||||||
|
|
||||||
|
assert_equal 1, @connection.foreign_keys("astronauts").size
|
||||||
|
@connection.remove_foreign_key :astronauts, :rockets
|
||||||
|
assert_equal [], @connection.foreign_keys("astronauts")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_remove_foreign_key_by_column
|
||||||
@connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
|
@connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
|
||||||
|
|
||||||
assert_equal 1, @connection.foreign_keys("astronauts").size
|
assert_equal 1, @connection.foreign_keys("astronauts").size
|
||||||
|
|
Loading…
Reference in a new issue