Skip to content

Instantly share code, notes, and snippets.

@cgimenes
Created August 25, 2021 10:27
Show Gist options
  • Save cgimenes/157c6fad811e8bc32c4185f0686ae644 to your computer and use it in GitHub Desktop.
Save cgimenes/157c6fad811e8bc32c4185f0686ae644 to your computer and use it in GitHub Desktop.
Better enum solution for Rails

Migration Generation

rails g migration add_status_to_catalogs status:catalog_status

Migration

class AddStatusToCatalogs < ActiveRecord::Migration[5.1]
  def up
    execute <<-SQL
      CREATE TYPE catalog_status AS ENUM ('published', 'unpublished', 'not_set');
    SQL
    add_column :catalogs, :status, :catalog_status
    add_index :catalogs, :status
  end

  def down
    remove_column :catalogs, :status
    execute <<-SQL
      DROP TYPE catalog_status;
    SQL
  end
end

Value Object

class CatalogStatus
  STATUSES = %w(published unpublished not_set).freeze

  def initialize(status)
    @status = status
  end

  # what you need here
end

Model

class Catalog
  enum status: array_to_enum_hash(CatalogStatus::STATUSES), _suffix: true

  def status
    @status ||= CatalogStatus.new(read_attribute(:status))
  end
end

Helper function

def array_to_enum_hash(a)
  a.reduce({}) {|acc, x| acc.update(x.to_sym => x.to_s)}
end
@CoderMiguel
Copy link

CoderMiguel commented Feb 26, 2023

This seems to be the final solution from this Blog: https://naturaily.com/blog/ruby-on-rails-enum
The write-up was helpful, in my option, as it breaks down all of the components.

However there is no explanation of the array_to_enum_hash method in the blog.

id recommend:

def array_to_enum_hash(a)
  a.index_with(&:to_s).symbolize_keys
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment