Rails 8 Adds if_not_exists Option On The add_enum_value.

Rails 7 added support for custom enum types in PostgreSQL with introduction of create_enum to add a new enum type and t.enum to add a column.

Rails 7.1 has extended the ability to rename an enum, add enum value and rename enum value for the Postgres database adapter.

The add_enum_value method provides a straightforward way to add new values to a PostgreSQL enum type without needing to execute raw SQL.

class AddEnumToArticles < ActiveRecord::Migration[7.2]
  def change
    create_enum :status, ["draft", "published", "archived", "trashed"]

    safety_assured do
      change_table :articles do |t|
        t.enum :current_status, enum_type: "status", default: "draft", null: false
      end
    end
  end
end
class AddReviewToArticleStatus < ActiveRecord::Migration[7.2]
  def change
    add_enum_value :status, 'review'
  end
end

Before

When we use add_enum_value, PostgreSQL checks for duplicates and raises a PG::DuplicateObject error if a value already exists. ActiveRecord captures this as ActiveRecord::StatementInvalid when trying to add a duplicate value.

class AddReviewToArticleStatus < ActiveRecord::Migration[7.2]
  def change
    add_enum_value :status, 'review'
  end
end
PG::DuplicateObject: ERROR:  enum label "review" already exists

ActiveRecord::StatementInvalid: PG::DuplicateObject: ERROR:  enum label "review" already exists (ActiveRecord::StatementInvalid)

To avoid the adding of dubplicate enums, we can use PostgreSQL IF NOT EXISTS but it only works with raw SQL. So we can not use it with add_enum_value.

After

Rails 8 adds support for PostgreSQL IF NOT EXISTS functionality with the introduction of if_not_exists option on the add_enum_value method.

With this if_not_exists option, we can now safely add a new enum value, preventing errors if the value already exists.

class AddReviewToArticleStatus < ActiveRecord::Migration[8.0]
  def change
    add_enum_value :status, 'review', if_not_exists: true
  end
end

If the enum doesn’t exist then the above migration will add the enum otherwise it won’t raise an error.

Need help on your Ruby on Rails or React project?

Join Our Newsletter