Skip to content

Commit d191c4f

Browse files
authored
Merge pull request rails#53795 from fatkodima/fix-constraint-methods-be-revertible-with-invalid-options
Fix add_unique_constraint/add_check_constraint/add_foreign_key to be revertible when given invalid options
2 parents 2aa67ec + b4fdd35 commit d191c4f

File tree

4 files changed

+63
-0
lines changed

4 files changed

+63
-0
lines changed

activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ def export_name_on_schema_dump?
159159
end
160160

161161
def defined_for?(to_table: nil, validate: nil, **options)
162+
options = options.slice(*self.options.keys)
163+
162164
(to_table.nil? || to_table.to_s == self.to_table) &&
163165
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
164166
options.all? { |k, v| Array(self.options[k]).map(&:to_s) == Array(v).map(&:to_s) }
@@ -185,6 +187,8 @@ def export_name_on_schema_dump?
185187
end
186188

187189
def defined_for?(name:, expression: nil, validate: nil, **options)
190+
options = options.slice(*self.options.keys)
191+
188192
self.name == name.to_s &&
189193
(validate.nil? || validate == self.options.fetch(:validate, validate)) &&
190194
options.all? { |k, v| self.options[k].to_s == v.to_s }

activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ def export_name_on_schema_dump?
232232
end
233233

234234
def defined_for?(name: nil, column: nil, **options)
235+
options = options.slice(*self.options.keys)
236+
235237
(name.nil? || self.name == name.to_s) &&
236238
(column.nil? || Array(self.column) == Array(column).map(&:to_s)) &&
237239
options.all? { |k, v| self.options[k].to_s == v.to_s }

activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def remove_foreign_key(from_table, to_table = nil, **options)
7575
Base.pluralize_table_names ? table.pluralize : table
7676
end
7777
table = strip_table_name_prefix_and_suffix(table)
78+
options = options.slice(*fk.options.keys)
7879
fk_to_table = strip_table_name_prefix_and_suffix(fk.to_table)
7980
fk_to_table == table && options.all? { |k, v| fk.options[k].to_s == v.to_s }
8081
end || raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")

activerecord/test/cases/invertible_migration_test.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def change
1919
t.column :content, :text
2020
t.column :remind_at, :datetime
2121
t.column :place_id, :integer
22+
t.column :parent_id, :bigint
2223
end
2324
end
2425
end
@@ -220,6 +221,24 @@ def change
220221
end
221222
end
222223

224+
class RevertUniqueConstraintWithInvalidOption < SilentMigration
225+
def change
226+
add_unique_constraint :horses, :place_id, invalid: :option
227+
end
228+
end
229+
230+
class RevertForeignKeyWithInvalidOption < SilentMigration
231+
def change
232+
add_foreign_key :horses, :horses, column: :parent_id, invalid: :option
233+
end
234+
end
235+
236+
class RevertCheckConstraintWithInvalidOption < SilentMigration
237+
def change
238+
add_check_constraint :horses, "place_id > 0", invalid: :option
239+
end
240+
end
241+
223242
self.use_transactional_tests = false
224243

225244
setup do
@@ -526,5 +545,42 @@ def test_up_only
526545
assert_not connection.column_exists?(:horses, :oldie)
527546
Horse.reset_column_information
528547
end
548+
549+
if ActiveRecord::Base.lease_connection.supports_unique_constraints?
550+
def test_migrate_revert_add_unique_constraint_with_invalid_option
551+
InvertibleMigration.new.migrate(:up)
552+
RevertUniqueConstraintWithInvalidOption.new.migrate(:up)
553+
554+
connection = ActiveRecord::Base.lease_connection
555+
assert_equal 1, connection.unique_constraints(:horses).count
556+
557+
RevertUniqueConstraintWithInvalidOption.new.migrate(:down)
558+
assert_empty connection.unique_constraints(:horses)
559+
end
560+
end
561+
562+
def test_migrate_revert_add_foreign_key_with_invalid_option
563+
InvertibleMigration.new.migrate(:up)
564+
RevertForeignKeyWithInvalidOption.new.migrate(:up)
565+
566+
connection = ActiveRecord::Base.lease_connection
567+
assert_equal 1, connection.foreign_keys(:horses).count
568+
569+
RevertForeignKeyWithInvalidOption.new.migrate(:down)
570+
assert_empty connection.foreign_keys(:horses)
571+
end
572+
573+
if ActiveRecord::Base.lease_connection.supports_check_constraints?
574+
def test_migrate_revert_add_check_constraint_with_invalid_option
575+
InvertibleMigration.new.migrate(:up)
576+
RevertCheckConstraintWithInvalidOption.new.migrate(:up)
577+
578+
connection = ActiveRecord::Base.lease_connection
579+
assert_equal 1, connection.check_constraints(:horses).count
580+
581+
RevertCheckConstraintWithInvalidOption.new.migrate(:down)
582+
assert_empty connection.check_constraints(:horses)
583+
end
584+
end
529585
end
530586
end

0 commit comments

Comments
 (0)