Skip to content

Commit

Permalink
Fix migration compatibility to create SQLite references/belongs_to co…
Browse files Browse the repository at this point in the history
…lumn as a integer when migration version is 6.0

Since #38717 the `ReferenceDefinition` wasn't being
instantiated with the column type as `:integer` in
the compatibility module when the adapter is SQLite
for 6.0 migrations which make such columns be created
as `bigint` instead of `integer`. Differing from
the way they are created in prior versions or newer
versions, which is always `integer`.

Fixes #43168
  • Loading branch information
marcelolx committed Dec 7, 2021
1 parent 30ff804 commit 99eea87
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
7 changes: 7 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
* Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0.

Reference/belongs_to in migrations with version 6.0 were creating columns as
bigint instead of integer for the SQLite Adapter.

*Marcelo Lauxen*

* Add `authenticate_by` when using `has_secure_password`.

`authenticate_by` is intended to replace code like the following, which
Expand Down
26 changes: 24 additions & 2 deletions activerecord/lib/active_record/migration/compatibility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,22 @@ def index_options(table_name)
end
end

module SQLite3
module TableDefinition
def references(*args, **options)
args.each do |ref_name|
ReferenceDefinition.new(ref_name, type: :integer, **options).add_to(self)
end
end
alias :belongs_to :references

def column(name, type, index: nil, **options)
options[:precision] ||= nil
super
end
end
end

module TableDefinition
def references(*args, **options)
args.each do |ref_name|
Expand Down Expand Up @@ -131,15 +147,21 @@ def create_join_table(table_1, table_2, **options)
end

def add_reference(table_name, ref_name, **options)
ReferenceDefinition.new(ref_name, **options)
.add_to(connection.update_table_definition(table_name, self))
if connection.adapter_name == "SQLite"
reference_definition = ReferenceDefinition.new(ref_name, type: :integer, **options)
else
reference_definition = ReferenceDefinition.new(ref_name, **options)
end

reference_definition.add_to(connection.update_table_definition(table_name, self))
end
alias :add_belongs_to :add_reference

private
def compatible_table_definition(t)
class << t
prepend TableDefinition
prepend SQLite3::TableDefinition
end
t
end
Expand Down
44 changes: 44 additions & 0 deletions activerecord/test/cases/migration/compatibility_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,50 @@ def migrate(x)
assert connection.column_exists?(:testings, :published_at, **precision_implicit_default)
end

if current_adapter?(:SQLite3Adapter)
def test_references_stays_as_integer_column_on_create_table_with_reference_6_0
migration = Class.new(ActiveRecord::Migration[6.0]) {
def migrate(x)
create_table :more_testings do |t|
t.references :testings
end
end
}.new

ActiveRecord::Migrator.new(:up, [migration], @schema_migration).migrate

testings_id_column = connection.columns(:more_testings).find { |el| el.name == "testings_id" }
assert_equal "integer", testings_id_column.sql_type
ensure
connection.drop_table :more_testings rescue nil
end

def test_references_stays_as_integer_column_on_add_reference_6_0
create_migration = Class.new(ActiveRecord::Migration[6.0]) {
def version; 100 end
def migrate(x)
create_table :more_testings do |t|
t.string :test
end
end
}.new

migration = Class.new(ActiveRecord::Migration[6.0]) {
def version; 101 end
def migrate(x)
add_reference :more_testings, :testings
end
}.new

ActiveRecord::Migrator.new(:up, [create_migration, migration], @schema_migration).migrate

testings_id_column = connection.columns(:more_testings).find { |el| el.name == "testings_id" }
assert_equal "integer", testings_id_column.sql_type
ensure
connection.drop_table :more_testings rescue nil
end
end

private
def precision_implicit_default
if current_adapter?(:Mysql2Adapter)
Expand Down

0 comments on commit 99eea87

Please sign in to comment.