Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix migration compatibility to create SQLite references/belongs_to column as a integer when migration version is 6.0 #43295

Merged
merged 1 commit into from
Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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