Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extract Ruby on Rails enum values into a dictionary (represented by markdown tables).

README

Sometimes you have members from your data team who are looking at the database and have no idea what the enum integer values mean. This snippet of code helps to extract the readable names for those integers into markdown tables to help out your data team.

There are alternative approaches by using string enums via gems, or database enums, but this was made for an environment where those weren't an option (legacy enums, and no database enums available).

You could also put this into a Rake task and publish it into a wiki.

Usage

enum_mappings = extract_enum_mappings_from_all_models
markdown = enum_mappings_to_markdown(enum_mappings)

puts markdown

Check the sample below to see how the markdown looks like.

def extract_enum_mappings(model_class)
return nil unless model_class.table_exists?
attribute_types = model_class.attribute_types
enums = attribute_types.select{ |key, value| value.class == ActiveRecord::Enum::EnumType }
return nil if enums.blank?
enum_mappings = {}
enum_values = enums.values
enum_values.each do |enum_value|
enum_mappings[enum_value.send(:name)] = enum_value.send(:mapping)
end
enum_mappings
end
# Returns a hash that looks like this:
# {
# "User"=> {:values => {"type"=>{"customer"=>0, "developer"=>1} }, :table_name => "users"},
# ...
# }
def extract_enum_mappings_from_all_models
enum_mappings = {}
ApplicationRecord.descendants.each do |model_class|
enum_values = extract_enum_mappings(model_class)
next if enum_values.blank?
enum_mappings[model_class.name] = {
values: extract_enum_mappings(model_class),
table_name: model_class.table_name,
}
end
enum_mappings.compact
end
def enum_mappings_to_markdown(enum_mappings)
markdown = ""
enum_mappings.each do |model_name, data|
markdown += "# #{data[:table_name]}\n\n"
data[:values].each do |attribute, values|
markdown += "## #{attribute}\n\n"
markdown += "| name | value |\n"
markdown += "| ----------- | ----------- |\n"
values.each do |value, id|
markdown += "| #{value} | #{id} |\n"
end
markdown += "\n"
end
end
markdown
end

users

status

name value
unverified 0
verified 1
blocked 2

type

name value
buyer 0
developer 1
merchant 2

orders

status

name value
created 0
waiting_for_payment 1
payment_complete 2
shipped 3
delievered 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment