Search code examples
rubymetaprogramming

Using Module#prepend to interrogate a str_enum


I have a Rails model, which is using the str_enum gem.

I'm building a generator which reads the models and creates pages for them, and so I'd like to be able to understand what str_enums are attached to a model.

For example

class User < ApplicationRecord
  str_enum :email_frequency, %i[every daily weekly], default: 'every'
end

Ideally, I'd like to be able to query the User model and understand there is a str_enum attached to email_frequency, with values of every, daily & weekly.

Once I can understand there is a str_enum attached to a given field, I can pluralize the field and get the values:

irb(main):004:0> User.email_frequencies
=> ["every", "daily", "weekly"]

The question has also be asked over here and the suggestion is to use Module#prepend. I'm familiar with prepend to conditionally insert methods into a model.

How can I use it for this problem?

EDIT

This is quite simple with validations, for example: get validations from model


Solution

  • If I understand your question correctly is that you wanna get all column that has attached with enum string. If so you can override the gem method like this

    # lib/extenstions/str_enum.rb
    
    module Extensions
      module StrEnum
        module ClassMethods
          def str_enum(column, *args)
            self.str_enums << column.to_s.pluralize
            super
          end
        end
    
        def self.prepended(base)
          class << base
            mattr_accessor :str_enums
            self.str_enums = []
            prepend ClassMethods
          end
        end
      end
    end
    
    

    In the User model

    prepend Extensions::StrEnum
    
    

    Now you can use

    User.str_enums
    

    to list all columns has attached with str enum.

    Make sure you have add lib directory into load path.