[ActiveRecord] Return enum values as instances of ActiveSupport::StringInquirer

Sometimes the options of an ActiveRecord enum don’t make sense outside the context of the enum’s name.
For example:

class User < ApplicationRecord
enum authentication_strategy: [:disabled, :password, :captcha]


Calling @user.password? would not make much sense.

Of course we could prefix this so that it instead reads @user.authentication_strategy_password?.
This still reads a bit oddly to me.

Using ActiveSupport’s StringInquirer, we could instead do: @user.authentication_strategy.password?.
To me, this approach makes it most clear that *password? refers specifically to the concept of authentication_strategy.

I’d support an additional method called enum_with_prefix that does as you describe :+1:

I’m afraid that verbiage may confuse some people since we already use the term ‘prefix’ in the enum method:
enum authentication_strategy: [:disabled, :password, :captcha], prefix: true

Do you have any concerns about returning a StringInquirer instead of a String by default?

Returning a StringInquirer in a place where it’s not currently expected is a great way to break existing code – two things immediately come to mind:

  • Serialization/deserialization

  • Wrapping/subclassing built-in classes often has unexpected results since it’s hard to guarantee you maintain all behavior (particularly in compatibility with other code)

Side note: I think adding more StringInquirer usages in general obfuscates the intent of code because it masks the simplicity of what’s actually going on. But even if we don’t agree on that note, I believe quite strongly that we shouldn’t change the API like this just because of a minor improvement to certain magical use cases.

Forgot that we already have _prefix/_suffix!

For your original case, I would use the _suffix instead to get a more natural sounding api: @user.password_authentication_strategy?

Suffix does end up reading pretty well…
I don’t really see any reasonable case to be made for the change at this point (although I still like the idea).

Thanks for talking it over.

I think this topic can be closed.