Module: StrongMigrations::MigrationHelpers

Defined in:
lib/strong_migrations/migration_helpers.rb

Instance Method Summary collapse

Instance Method Details

#add_foreign_key_safely(from_table, to_table, **options) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/strong_migrations/migration_helpers.rb', line 3

def add_foreign_key_safely(from_table, to_table, **options)
  ensure_postgresql(__method__)
  ensure_not_in_transaction(__method__)

  reversible do |dir|
    dir.up do
      if ActiveRecord::VERSION::STRING >= "5.2"
        add_foreign_key(from_table, to_table, options.merge(validate: false))
        validate_foreign_key(from_table, to_table)
      else
        options = connection.foreign_key_options(from_table, to_table, options)
        fk_name, column, primary_key = options.values_at(:name, :column, :primary_key)
        primary_key ||= "id"

        statement = ["ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)"]
        statement << on_delete_update_statement(:delete, options[:on_delete]) if options[:on_delete]
        statement << on_delete_update_statement(:update, options[:on_update]) if options[:on_update]
        statement << "NOT VALID"

        safety_assured do
          execute quote_identifiers(statement.join(" "), [from_table, fk_name, column, to_table, primary_key])
          execute quote_identifiers("ALTER TABLE %s VALIDATE CONSTRAINT %s", [from_table, fk_name])
        end
      end
    end

    dir.down do
      remove_foreign_key(from_table, to_table)
    end
  end
end

#add_null_constraint_safely(table_name, column_name, name: nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/strong_migrations/migration_helpers.rb', line 35

def add_null_constraint_safely(table_name, column_name, name: nil)
  ensure_postgresql(__method__)
  ensure_not_in_transaction(__method__)

  reversible do |dir|
    dir.up do
      name ||= null_constraint_name(table_name, column_name)

      safety_assured do
        execute quote_identifiers("ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s IS NOT NULL) NOT VALID", [table_name, name, column_name])
        execute quote_identifiers("ALTER TABLE %s VALIDATE CONSTRAINT %s", [table_name, name])
      end
    end

    dir.down do
      remove_null_constraint_safely(table_name, column_name)
    end
  end
end

#remove_null_constraint_safely(table_name, column_name, name: nil) ⇒ Object

removing constraints is safe, but this method is safe to reverse as well



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/strong_migrations/migration_helpers.rb', line 56

def remove_null_constraint_safely(table_name, column_name, name: nil)
  # could also ensure in transaction so it can be reversed
  # but that's more of a concern for a reversible migrations check
  ensure_postgresql(__method__)

  reversible do |dir|
    dir.up do
      name ||= null_constraint_name(table_name, column_name)

      safety_assured do
        execute quote_identifiers("ALTER TABLE %s DROP CONSTRAINT %s", [table_name, name])
      end
    end

    dir.down do
      add_null_constraint_safely(table_name, column_name)
    end
  end
end