How to use Postgres Enums with Rails 7

#codesummary #code #summary #rails #rails7 #postgresql #enums

# Part 1/3: How to create an enum type for an Active Record Model def up create_enum :user_status, ["pending", "active", "archived"] # creating enum type create_table :users, force: true do |t| t.enum :status, enum_type: "user_status", default: "pending", null: false end end def down drop_table :users execute <<-SQL DROP TYPE user_status; SQL end # This is how the model might look like when using standard Rails class User < ActiveRecord::Base enum status: { pending: 'pending', active: 'active', }, _prefix: true end # the following queries will work User.status_pending.count user.status_pending?
# Code Summary for https://allaboutcoding.ghinda.com/how-to-work-with-postgresql-enums-in-rails-7 # Part 2/3: How to add a new value or how to rename disable_ddl_transaction def up execute <<-SQL ALTER TYPE user_status ADD VALUE IF NOT EXISTS 'disabled' AFTER 'active'; SQL end def up execute <<-SQL ALTER TYPE user_status RENAME VALUE 'pending' TO 'waiting'; SQL # don't forget to change the default status if you renamed the default one change_column_default :users, :status, from: 'pending', to: 'waiting' end
# Code Summary for https://allaboutcoding.ghinda.com/how-to-work-with-postgresql-enums-in-rails-7 # Part 3/3: How to delete a value from the enum type def up # First, make sure no records are using the status that you want to remove User.status_waiting.update_all(status: 'pending') # change default to nil change_column_default :users, :status, nil execute <<-SQL --- Rename the old enum ALTER TYPE user_status RENAME TO user_status_old; --- Create the new enum as you will like it to be CREATE TYPE user_status AS ENUM('pending', 'active', 'archived'); --- Alter the table to update it to use the new enum ALTER TABLE users ALTER COLUMN status TYPE user_status USING users::text::user_status; --- Drop the old status DROP TYPE user_status_old; SQL # make the default status pending change_column_default :users, :status, 'pending' end

If you want to play with the code, I create a single file Rails app here: postgres_enums_in_rails_7.rb

Reply

or to participate.