[Proposal] Add `as: :string` to `ActiveRecord::Enum` to make a string backed enum

We’re starting to use string backed enums in our models as it’s really helpful for reporting and also fixes the ordering issue (yes I know you can use hash based enums).

Currently it looks like this if you want to derive the values from the keys:

enum :fruit, %i[apples oranges pears].index_with(&:to_s)

I’d like to make it look like this:

enum :fruit, %i[apples oranges pears], as: :string # or string: true

Or perhaps even derive it from the column type.

I’d be happy to take a crack at coding this up. Just wanted to see if there is interest and have a convo on the syntax.

Cheers, Phil

5 Likes

I think it would be really cool if you could derive this from the column type.

3 Likes

If you do make a PR, you’ll not only want to account for string columns. In Postgres you can define custom enum type columns that work really nicely with “string” ActiveRecord enums. These Postgres enums use less bytes in the database and enforce enum values at the database level. So it’d be nice if this new feature applied to those too.

like this:

enum :status, { draft: “draft”, published: “published”, archived: “archived” }, default: “draft”

Wow! I’d completely forgotten about enums in PostgreSQL! That Rails now supports them is pretty cool. I’ll certainly see about supporting them too. This is probably the more preferred use of enums going forward anyway. It’s got a stronger case against both string and int enums if database portability is not a concern.

We know what the syntax currently is, this discussion is about DRYing the hash. I think using the array based syntax and checking the schema for the type would be sweet. I’ve not delved into the Rails codebase for many years so we’ll see how this goes.

Yeah, they’re pretty cool. And although the column type is an enum, ActiveRecord basically just interacts with it like a string, which is why I hope it’s not that big of a lift to extend this to Postgres Enums too.