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 ecc6caa8f29bf3e0d21355f105a816bb5ae7337f..87144fe86f2d39d0b5984514c74984cd9543d8b9 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -354,8 +354,8 @@ def timestamps(**options) # # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use. def references(*args, **options) - args.each do |col| - ReferenceDefinition.new(col, **options).add_to(self) + args.each do |ref_name| + ReferenceDefinition.new(ref_name, options).add_to(self) end end alias :belongs_to :references @@ -589,8 +589,7 @@ def rename(column_name, new_column_name) # t.belongs_to(:supplier, foreign_key: true) # # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use. - def references(*args) - options = args.extract_options! + def references(*args, **options) args.each do |ref_name| @base.add_reference(name, ref_name, options) end @@ -603,8 +602,7 @@ def references(*args) # t.remove_belongs_to(:supplier, polymorphic: true) # # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference] - def remove_references(*args) - options = args.extract_options! + def remove_references(*args, **options) args.each do |ref_name| @base.remove_reference(name, ref_name, options) end 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 7d602faf304d5d8482a4b1c43aa08c02962669a3..cf1241bf0caf10243955fdd7853d4bcaf345aa21 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -828,8 +828,8 @@ def index_name_exists?(table_name, index_name, default) # # add_reference(:products, :supplier, foreign_key: {to_table: :firms}) # - def add_reference(table_name, *args) - ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self)) + def add_reference(table_name, ref_name, **options) + ReferenceDefinition.new(ref_name, options).add_to(update_table_definition(table_name, self)) end alias :add_belongs_to :add_reference diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb index f9bb7e6d82e63fc6d0cc66f2e324dfde08b6fcf5..e157e4b218aa87d1853d75ddf77be935de24f56f 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb @@ -13,6 +13,11 @@ def primary_key(name, type = :primary_key, **options) class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition include ColumnMethods + + def references(*args, **options) + super(*args, type: :integer, **options) + end + alias :belongs_to :references end class Table < ActiveRecord::ConnectionAdapters::Table diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index ca6de37a6b2e4d4616e0ad9399c26933a152b669..3d728d74cfe341043abb9839322b2b3469407101 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -443,6 +443,11 @@ def rename_column(table_name, column_name, new_column_name) #:nodoc: rename_column_indexes(table_name, column.name, new_column_name) end + def add_reference(table_name, ref_name, **options) # :nodoc: + super(table_name, ref_name, type: :integer, **options) + end + alias :add_belongs_to :add_reference + def foreign_keys(table_name) fk_info = select_all("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA") fk_info.map do |row| diff --git a/activerecord/lib/active_record/migration/compatibility.rb b/activerecord/lib/active_record/migration/compatibility.rb index f6c9127d34171ad3f9c2ff4e8cf364d9ff19c573..ffb54f5137acb114125c19008e5c3220476d1590 100644 --- a/activerecord/lib/active_record/migration/compatibility.rb +++ b/activerecord/lib/active_record/migration/compatibility.rb @@ -14,6 +14,13 @@ def self.find(version) V5_1 = Current class V5_0 < V5_1 + module TableDefinition + def references(*args, **options) + super(*args, type: :integer, **options) + end + alias :belongs_to :references + end + def create_table(table_name, options = {}) if adapter_name == "PostgreSQL" if options[:id] == :uuid && !options.key?(:default) @@ -34,8 +41,35 @@ def create_table(table_name, options = {}) options[:id] = :integer end - super + if block_given? + super(table_name, options) do |t| + class << t + prepend TableDefinition + end + yield t + end + else + super + end end + + def change_table(table_name, options = {}) + if block_given? + super(table_name, options) do |t| + class << t + prepend TableDefinition + end + yield t + end + else + super + end + end + + def add_reference(table_name, ref_name, **options) + super(table_name, ref_name, type: :integer, **options) + end + alias :add_belongs_to :add_reference end class V4_2 < V5_0 diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index a2b7d532054675c6af559d3c1e28dc3b24c4eb7c..0c9d1dff9d5695b8930b3a7f2c45b61e8b65cfaf 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -194,7 +194,7 @@ def test_value_limit_violations_are_translated_to_specific_exception def test_numeric_value_out_of_ranges_are_translated_to_specific_exception error = assert_raises(ActiveRecord::RangeError) do - Book.connection.create("INSERT INTO books(author_id) VALUES (2147483648)") + Book.connection.create("INSERT INTO books(author_id) VALUES (9223372036854775808)") end assert_not_nil error.cause diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index a611cc208c899e1d23fdf455f7e00ccc0b3b70b3..979a59f566504ca0c623fb49cbbc818c4b92a0ca 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -98,6 +98,13 @@ def test_primary_key_with_no_id assert_nil Edge.primary_key end + def test_primary_key_and_references_columns_should_be_identical_type + pk = Author.columns_hash["id"] + ref = Post.columns_hash["author_id"] + + assert_equal pk.bigint?, ref.bigint? + end + def test_many_mutations car = Car.new name: "<3<3<3" car.engines_count = 0 diff --git a/activerecord/test/cases/migration/compatibility_test.rb b/activerecord/test/cases/migration/compatibility_test.rb index fc3ec47825be829285aa67c7755bee8d6fe1f27b..7a80bfb899426334606b29c48f166a451220b764 100644 --- a/activerecord/test/cases/migration/compatibility_test.rb +++ b/activerecord/test/cases/migration/compatibility_test.rb @@ -138,6 +138,7 @@ def test_legacy_primary_key_should_be_auto_incremented @migration = Class.new(ActiveRecord::Migration[5.0]) { def change create_table :legacy_primary_keys do |t| + t.references :legacy_ref end end }.new @@ -148,6 +149,9 @@ def change assert_not legacy_pk.bigint? assert_not legacy_pk.null + legacy_ref = LegacyPrimaryKey.columns_hash["legacy_ref_id"] + assert_not legacy_ref.bigint? + record1 = LegacyPrimaryKey.create! assert_not_nil record1.id diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb index 96e775a58b792db75543f65efab54373d51f0746..2258290a3cbe3d3d26d7930999fa2e43cfc2d8db 100644 --- a/activerecord/test/cases/migration/foreign_key_test.rb +++ b/activerecord/test/cases/migration/foreign_key_test.rb @@ -247,7 +247,7 @@ def change create_table("cities") { |t| } create_table("houses") do |t| - t.column :city_id, :bigint + t.references :city end add_foreign_key :houses, :cities, column: "city_id" @@ -279,7 +279,7 @@ def change create_table(:schools) create_table(:classes) do |t| - t.column :school_id, :bigint + t.references :school end add_foreign_key :classes, :schools end diff --git a/activerecord/test/cases/migration/references_foreign_key_test.rb b/activerecord/test/cases/migration/references_foreign_key_test.rb index 560adcbfedb5c4056c65f2813336b7a8b2022594..9418995ea0ea74057a06e64c33e5bae2dd19ccee 100644 --- a/activerecord/test/cases/migration/references_foreign_key_test.rb +++ b/activerecord/test/cases/migration/references_foreign_key_test.rb @@ -42,8 +42,7 @@ class ReferencesForeignKeyInCreateTest < ActiveRecord::TestCase test "options hash can be passed" do @connection.change_table :testing_parents do |t| - t.bigint :other_id - t.index :other_id, unique: true + t.references :other, index: { unique: true } end @connection.create_table :testings do |t| t.references :testing_parent, foreign_key: { primary_key: :other_id } @@ -110,8 +109,7 @@ class ReferencesForeignKeyTest < ActiveRecord::TestCase test "foreign keys accept options when changing the table" do @connection.change_table :testing_parents do |t| - t.bigint :other_id - t.index :other_id, unique: true + t.references :other, index: { unique: true } end @connection.create_table :testings @connection.change_table :testings do |t| @@ -195,18 +193,15 @@ def test_references_foreign_key_with_suffix test "multiple foreign keys can be added to the same table" do @connection.create_table :testings do |t| - t.bigint :col_1 - t.bigint :col_2 - - t.foreign_key :testing_parents, column: :col_1 - t.foreign_key :testing_parents, column: :col_2 + t.references :parent1, foreign_key: { to_table: :testing_parents } + t.references :parent2, foreign_key: { to_table: :testing_parents } end - fks = @connection.foreign_keys("testings") + fks = @connection.foreign_keys("testings").sort_by(&:column) fk_definitions = fks.map { |fk| [fk.from_table, fk.to_table, fk.column] } - assert_equal([["testings", "testing_parents", "col_1"], - ["testings", "testing_parents", "col_2"]], fk_definitions) + assert_equal([["testings", "testing_parents", "parent1_id"], + ["testings", "testing_parents", "parent2_id"]], fk_definitions) end end end diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 34c5f356b88cb06183514abd071c746a0f0a2ae8..1aed3e46c329e4034cfaf6d744d7c173e3e482fa 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -341,7 +341,7 @@ def up create_table("dogs") do |t| t.column :name, :string - t.column :owner_id, :bigint + t.references :owner t.index [:name] t.foreign_key :dog_owners, column: "owner_id" end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 4c31548fff78492cb8da89ceffa6f8293719edf4..08ff0336b970378bc9461ea76eb94ed9a37ae81b 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -54,8 +54,8 @@ create_table :authors, force: true do |t| t.string :name, null: false - t.bigint :author_address_id - t.integer :author_address_extra_id + t.references :author_address + t.references :author_address_extra t.string :organization_id t.string :owned_essay_id end @@ -88,7 +88,7 @@ end create_table :books, force: true do |t| - t.integer :author_id + t.references :author t.string :format t.column :name, :string t.column :status, :integer, default: 0 @@ -306,7 +306,7 @@ end create_table :engines, force: true do |t| - t.bigint :car_id + t.references :car, index: false end create_table :entrants, force: true do |t| @@ -664,8 +664,8 @@ end create_table :posts, force: true do |t| - t.integer :author_id - t.string :title, null: false + t.references :author + t.string :title, null: false # use VARCHAR2(4000) instead of CLOB datatype as CLOB data type has many limitations in # Oracle SELECT WHERE clause which causes many unit test failures if current_adapter?(:OracleAdapter)