Skip to content

Commit

Permalink
Fix for unsafe_remove_constraint_name to handle symbols in Rails < 7.1 (
Browse files Browse the repository at this point in the history
#102)

Rails versions < 7.1 errors when a symbol is used as the constraint name;
this bug is fixed in 7.1, and we want to make that experience consistent in
order versions.

Co-authored-by: Suraj Mishra <[email protected]>
  • Loading branch information
imsurajmishra and Suraj Mishra authored Jul 8, 2024
1 parent 77c3add commit 1548086
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/pg_ha_migrations/safe_statements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,12 @@ def safely_acquire_lock_for_table(table, mode: :access_exclusive, &block)
Thread.current[__method__] = nil unless nested_target_table
end

# since rails versions < 7.1 has bug which does not handle symbol for
# constraint name, we are converting name to string explicitly to solve that.
def raw_remove_check_constraint(table, name:, **options)
super(table, name: name.to_s, **options)
end

def adjust_lock_timeout(timeout_seconds = PgHaMigrations::LOCK_TIMEOUT_SECONDS, &block)
_check_postgres_adapter!
original_timeout = ActiveRecord::Base.value_from_sql("SHOW lock_timeout").sub(/s\Z/, '').to_i * 1000
Expand Down
36 changes: 36 additions & 0 deletions spec/safe_statements_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,42 @@ def up
end
end

describe "raw_remove_check_constraint" do
before(:each) do
setup_migration = Class.new(migration_klass) do
define_method(:up) do
unsafe_create_table :foos
unsafe_add_column :foos, :bar, :text
unsafe_add_check_constraint :foos, "bar IS NOT NULL", :name => :constraint_foo_bar_is_not_null
end
end
setup_migration.suppress_messages { setup_migration.migrate(:up) }
end

["constraint_foo_bar_is_not_null", :constraint_foo_bar_is_not_null].each do |constraint_name|
it "removes the check constraint when passed as a #{constraint_name.is_a?(Symbol) ? "symbol" : "string"}" do
migration = Class.new(migration_klass) do
# If 'def up' is used instead, we would lose access to the
# constraint_name local variable, so we use
# 'define_method(:up)'.
define_method(:up) do
raw_remove_check_constraint :foos, name: constraint_name
end
end

expect do
migration.suppress_messages { migration.migrate(:up) }
end.to change {
ActiveRecord::Base.connection.select_value <<~SQL
SELECT conname
FROM pg_constraint
WHERE conname = 'constraint_foo_bar_is_not_null'
SQL
}.from("constraint_foo_bar_is_not_null").to(nil)
end
end
end

describe "safe_make_column_nullable" do
it "removes the not null constraint from the column" do
migration = Class.new(migration_klass) do
Expand Down

0 comments on commit 1548086

Please sign in to comment.