diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index e9b4c241db6..4372e9f1396 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,8 @@ +* Add support for PostgreSQL `IF NOT EXISTS` via the `:if_not_exists` option + on the `add_enum_value` method. + + *Ariel Rzezak* + * When running `db:migrate` on a fresh database, load the database schema before running migrations. *Andrew Novoselac* diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 619a39f22bb..eaf7fae469b 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -584,7 +584,9 @@ module ActiveRecord # Add enum value to an existing enum type. def add_enum_value(type_name, value, options = {}) before, after = options.values_at(:before, :after) - sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE '#{value}'" + sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE" + sql << " IF NOT EXISTS" if options[:if_not_exists] + sql << " '#{value}'" if before && after raise ArgumentError, "Cannot have both :before and :after at the same time" diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb index 6cea300bed7..b1d58c9501d 100644 --- a/activerecord/test/cases/adapters/postgresql/enum_test.rb +++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb @@ -128,9 +128,14 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase @connection.add_enum_value :mood, :nervous, after: :ok @connection.add_enum_value :mood, :glad + assert_nothing_raised do + @connection.add_enum_value :mood, :glad, if_not_exists: true + @connection.add_enum_value :mood, :curious, if_not_exists: true + end + output = dump_table_schema("postgresql_enums") - assert_includes output, 'create_enum "mood", ["sad", "angry", "ok", "nervous", "happy", "glad"]' + assert_includes output, 'create_enum "mood", ["sad", "angry", "ok", "nervous", "happy", "glad", "curious"]' end def test_schema_dump_renamed_enum_value diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md index fc611975f68..1c4dfbb1740 100644 --- a/guides/source/active_record_postgresql.md +++ b/guides/source/active_record_postgresql.md @@ -332,6 +332,7 @@ def up add_enum_value :article_state, "archived" # will be at the end after published add_enum_value :article_state, "in review", before: "published" add_enum_value :article_state, "approved", after: "in review" + add_enum_value :article_state, "rejected", if_not_exists: true # won't raise an error if the value already exists end ```