ActiveModelでenumを使いたい

`ActiveModel::Model`をincludeしたクラスにenumを使いたい場面が出てきたけども、
ActiveRecordしか使えなさそうだったのと、検索しても出てこなかったので、
moduleを作成しました。
`ActiveModel::Attributes`を使うので`rails 5.2`以上の環境です。
未検証ですがそれ以下でも一応動くかもしれないです。

やっつけで作っているので、
enumで生成されるメソッドやオプション全てをカバーしていないのと、integerの項目にしか使えないです。

```rb:app/models/concerns/active_model/enum.rb
# frozen_string_literal: true

# ActiveModel::Attributesのattributeでenumを利用可能にするモジュール
# ただしintegerにしか使えない
# enum_helpのgemと同様に#{attribute}_i18nメソッドも追加する
module ActiveModel
  module Enum
    extend ActiveSupport::Concern

    module ClassMethods
      def enum(definitions)
        raise ArgumentError, 'enum attribute: { key: value, key, value, ...} の形式で指定してください' unless valid?(definitions)

        attribute = definitions.keys.first
        values = definitions.values.first

        # getterを上書き
        define_method(attribute.to_s) do
          values.invert[attributes[attribute.to_s]]
        end

        # 既存のsetterを別名に退避
        alias_method "#{attribute}_value=", "#{attribute}="

        # setterを上書き
        define_method("#{attribute}=") do |argument|
          checked_argument = case argument
                             when Integer
                               values.values.include?(argument) ? argument : nil
                             when String
                               values[argument.to_sym]
                             when Symbol
                               values[argument]
                             else
                               raise ArgumentError, 'string, symbol, integerのいずれかを指定してください'
                             end
          raise ArgumentError, "'#{argument}' is not a valid #{attribute}" if checked_argument.nil?

          send("#{attribute}_value=", checked_argument)
        end

        # enum_helpの_i18n的なメソッド追加
        define_method("#{attribute}_i18n") do
          enumed_value = send(attribute)
          I18n.t("enums.#{self.class.name.underscore}.#{attribute}.#{enumed_value}", default: enumed_value.to_s)
        end
      end

      private

      def valid?(definitions)
        return false unless definitions.is_a?(Hash)
        return false if definitions.keys.size != 1

        values = definitions.values.first
        return false unless values.is_a?(Hash)
        return false unless values.keys.all? { |key| key.is_a?(Symbol) }
        return false unless values.values.all? { |value| value.is_a?(Integer) }

        true
      end
    end
  end
end
```
使い方

```rb:app/models/sample.rb
class Sample
  include ActiveModel::Model
  include ActiveModel::Attributes
  include ActiveModel::Enum

  attribute :column_name, :integer

  enum column_name: { hoge: 1, piyo: 2, fuga: 3 }
end
```

```yml:config/locales/ja.yml
ja:
  enums:
    sample:
      column:
        hoge: ほげ
        piyo: ぴよ
        fuga: ふが
```

rails consoleで確認

```irb_output
irb(main):001:0> sample = Sample.new
=> #<Sample:0x000055ec983b15e8 @attributes=#<ActiveModel::AttributeSet:0x000055ec983b14a8 @attributes={"column"=>#<ActiveModel::Attribute::WithCastValue:0x000055ec983b1340 @name="column", @value_before_type_cast=nil, @type=#<ActiveModel::Type::Integer:0x00007f3e74051ea0 @precision=nil, @scale=nil, @limit=nil, @range=-2147483648...2147483648>, @original_attribute=nil>}>>
irb(main):002:0> sample.column = 1
=> 1
irb(main):003:0> sample.column
=> :hoge
irb(main):004:0> sample.column = 'piyo'
=> 'piyo'
irb(main):005:0> sample.column
=> :piyo
irb(main):006:0> sample.column_i18n
=> "ぴよ"
irb(main):007:0> sample.column = 4
Traceback (most recent call last):
        2: from (irb):6
        1: from app/models/concerns/active_model/enum.rb:37:in `block in enum'
ArgumentError ('4' is not a valid column)
```