enumy 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/enumy/enum.rb +65 -0
- data/lib/enumy/errors.rb +6 -0
- data/lib/enumy/model.rb +34 -19
- data/lib/enumy/rails/active_job/serializers/enum_serializer.rb +30 -0
- data/lib/enumy/rails/active_model/type/enum.rb +34 -0
- data/lib/enumy/rails/enum.rb +47 -0
- data/lib/enumy/rails/generators/enumy/install/install_generator.rb +13 -0
- data/lib/enumy/rails/generators/enumy/install/templates/app/enums/application_enum.rb +3 -0
- data/lib/enumy/rails/initializer_interceptor.rb +12 -0
- data/lib/enumy/rails/model.rb +34 -0
- data/lib/enumy/rails/railtie.rb +4 -4
- data/lib/enumy/version.rb +1 -1
- data/lib/enumy.rb +7 -11
- metadata +11 -13
- data/lib/enumy/active_job/serializers/enum_serializer.rb +0 -28
- data/lib/enumy/active_model/type/enum.rb +0 -32
- data/lib/enumy/base.rb +0 -87
- data/lib/enumy/generators/enumy/install/install_generator.rb +0 -22
- data/lib/enumy/generators/enumy/install/templates/app/enums/application_enum.rb +0 -3
- data/lib/enumy/test_helpers.rb +0 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c5a41d5b566db44a73694cda348ebdafd92ba493df67811989767da5ded37a32
|
|
4
|
+
data.tar.gz: 650fea0c0613b094a3323122fc6e95b7b0df42e6ee16a748b8f062ab2fb3f712
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c0bafe3cd2eec7e47741617d0455b208d168559d3a972ca9b800efa1a8edbd1e4a7b451b95ee949d218411696a2deef5a31bcd24029e0e08d138a4faa8c8ce0
|
|
7
|
+
data.tar.gz: 98f2c6f8d26fcfb6f2067c97ae205807e8cab6835b5fb992fa3ec7f8e0d3f3e63b04eb8417b7ebe5b12be52cf143852007304d0b8ed9c77edff3ff8363284116
|
data/lib/enumy/enum.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'enumy/errors'
|
|
2
|
+
|
|
3
|
+
module Enumy
|
|
4
|
+
class Enum
|
|
5
|
+
|
|
6
|
+
attr_reader :key
|
|
7
|
+
|
|
8
|
+
def initialize(key)
|
|
9
|
+
raise Errors::KeyMissingError.new(self) if key.nil?
|
|
10
|
+
@key = key.to_sym
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_s
|
|
14
|
+
key.to_s
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def inspect
|
|
18
|
+
attributes = instance_variables.map do |name|
|
|
19
|
+
value = instance_variable_get(name)
|
|
20
|
+
"#{name}: #{value.inspect}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
"#<#{self.class.name} #{attributes.join(', ')}>"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
|
|
28
|
+
def define(enum)
|
|
29
|
+
raise ArgumentError, "Expected an object of type `Enumy::Enum`, got #{enum.class.name}" unless enum.is_a?(Enumy::Enum)
|
|
30
|
+
|
|
31
|
+
if instances[enum.key]
|
|
32
|
+
raise Errors::DuplicateEnumInstanceError, "Enum `#{enum.key.to_s.upcase}` is using a duplicate key `#{enum.key}` for Enum '#{enum.class.name}'."
|
|
33
|
+
else
|
|
34
|
+
instances[enum.key] = enum
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def all
|
|
39
|
+
instances.values
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def find(key)
|
|
43
|
+
find_by(key: key.to_sym) || raise(Errors::EnumNotFoundError.new("Could not find a `#{self.name}` enum with a `key` of #{key}"))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def find_by(**args)
|
|
47
|
+
raise ArgumentError, "`find_by` requires at least one key-value pair" if args.empty?
|
|
48
|
+
|
|
49
|
+
instances.values.find do |instance|
|
|
50
|
+
args.all? do |attr, value|
|
|
51
|
+
instance.send(attr) == value
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def instances
|
|
59
|
+
@instances ||= {}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/enumy/errors.rb
CHANGED
|
@@ -5,5 +5,11 @@ module Enumy
|
|
|
5
5
|
class InvalidEnumClassError < NameError; end
|
|
6
6
|
class DuplicateEnumInstanceError < ArgumentError; end
|
|
7
7
|
|
|
8
|
+
class KeyMissingError < ArgumentError
|
|
9
|
+
def initialize(enum)
|
|
10
|
+
super("#{enum.class.name.upcase} enum requires a `key`")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
8
14
|
end
|
|
9
15
|
end
|
data/lib/enumy/model.rb
CHANGED
|
@@ -1,32 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require 'enumy/enum'
|
|
2
|
+
require 'enumy/errors'
|
|
3
3
|
|
|
4
4
|
module Enumy
|
|
5
5
|
module Model
|
|
6
|
-
def has_enum(name, class_name: name, **options)
|
|
7
|
-
enum_class = class_name.to_s.classify.safe_constantize
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
def has_enum(name, enum_class:, **options)
|
|
8
|
+
assert_valid_enum_type!(enum_class)
|
|
9
|
+
define_enum_methods(name, enum_class, default: options[:default])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def assert_valid_enum_value_type!(enum_class, enum)
|
|
13
|
+
return if enum.nil?
|
|
14
|
+
raise Errors::InvalidEnumClassError, "Expected instance of `#{enum_class}`, got instance of `#{enum.class}`" unless enum.is_a?(enum_class)
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
private
|
|
15
18
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
+
def define_enum_methods(name, enum_class, default: nil)
|
|
20
|
+
assert_valid_enum_value_type!(enum_class, default)
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
define_method(name) do
|
|
23
|
+
instance_variable_set("@#{name}", default) unless instance_variable_defined?("@#{name}")
|
|
24
|
+
instance_variable_get("@#{name}")
|
|
25
|
+
end
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
define_method("#{name}=") do |value|
|
|
28
|
+
case value
|
|
29
|
+
when Enumy::Enum, NilClass
|
|
30
|
+
self.class.assert_valid_enum_value_type!(enum_class, value)
|
|
31
|
+
instance_variable_set("@#{name}", value)
|
|
32
|
+
when String, Symbol
|
|
33
|
+
enum = enum_class.find(value)
|
|
34
|
+
instance_variable_set("@#{name}", enum)
|
|
35
|
+
else
|
|
36
|
+
raise ArgumentError
|
|
37
|
+
end
|
|
29
38
|
end
|
|
30
39
|
end
|
|
40
|
+
|
|
41
|
+
def assert_valid_enum_type!(enum_class)
|
|
42
|
+
raise Errors::InvalidEnumClassError, "`#{enum_class}` is not a constant" unless enum_class.is_a?(Module)
|
|
43
|
+
raise Errors::InvalidEnumClassError, "`#{enum_class.name}` does not inherit from `#{Enumy::Enum.name}`" unless enum_class.ancestors.include?(Enumy::Enum)
|
|
44
|
+
end
|
|
45
|
+
|
|
31
46
|
end
|
|
32
|
-
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'enumy/enum.rb'
|
|
2
|
+
|
|
3
|
+
module Enumy
|
|
4
|
+
module Rails
|
|
5
|
+
module ActiveJob
|
|
6
|
+
module Serializers
|
|
7
|
+
class EnumSerializer < ::ActiveJob::Serializers::ObjectSerializer
|
|
8
|
+
|
|
9
|
+
def serialize(enum)
|
|
10
|
+
super({ class: enum.class.name, key: enum.key.to_s })
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def deserialize(hash)
|
|
14
|
+
hash[:class].safe_constantize&.find_by(key: hash[:key].to_sym)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def serialize?(value)
|
|
18
|
+
value.is_a?(klass)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def klass
|
|
24
|
+
Enumy::Enum
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Enumy
|
|
2
|
+
module Rails
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Type
|
|
5
|
+
class Enum < ::ActiveModel::Type::Value
|
|
6
|
+
def initialize(enum_class)
|
|
7
|
+
@enum_class = enum_class
|
|
8
|
+
super()
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def cast(value)
|
|
12
|
+
value.is_a?(@enum_class) ? value : @enum_class.find_by(key: value&.to_sym)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def serialize(value)
|
|
16
|
+
if value.is_a?(@enum_class)
|
|
17
|
+
value.key.to_s
|
|
18
|
+
else
|
|
19
|
+
@enum_class.find_by(key: value&.to_sym) ? value&.to_s : nil
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def deserialize(value)
|
|
24
|
+
value.is_a?(@enum_class) ? value : @enum_class.find_by(key: value&.to_sym)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def type
|
|
28
|
+
:enum
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'enumy/rails/initializer_interceptor'
|
|
2
|
+
|
|
3
|
+
module Enumy
|
|
4
|
+
module Rails
|
|
5
|
+
class Enum < Enumy::Enum
|
|
6
|
+
include Enumy::Rails::InitializerInterceptor
|
|
7
|
+
include ::ActiveModel::Model
|
|
8
|
+
include ::ActiveModel::Attributes
|
|
9
|
+
|
|
10
|
+
attribute :key
|
|
11
|
+
|
|
12
|
+
def initialize(key, **attrs)
|
|
13
|
+
raise Errors::KeyMissingError.new(self) if key.nil?
|
|
14
|
+
super(key: key.to_sym, **attrs)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def titleize
|
|
18
|
+
key.to_s.titleize
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def human_attribute_name(attribute)
|
|
22
|
+
I18n.t("#{self.class.i18n_scope}.attributes.models.#{self.class.model_name.i18n_key}/#{self.key}.#{attribute}")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def name
|
|
26
|
+
human_attribute_name(:key)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def inspect
|
|
30
|
+
"#<#{self.class.name} #{attributes.map { |name, value| "#{name}: #{value.inspect}" }.join(', ')}>"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class << self
|
|
34
|
+
|
|
35
|
+
def model_name
|
|
36
|
+
@model_name ||= ::ActiveModel::Name.new(self, nil, self.name.to_s)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def i18n_scope
|
|
40
|
+
:enum
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module Enumy
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
def copy_application_enum
|
|
9
|
+
template "app/enums/application_enum.rb", "app/enums/application_enum.rb"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Enumy
|
|
2
|
+
module Rails
|
|
3
|
+
module InitializerInterceptor
|
|
4
|
+
def initialize
|
|
5
|
+
# Intentionally left blank to intercept the original initialize method
|
|
6
|
+
# We do this because we want to use ActiveModel::Attributes for attribute handling
|
|
7
|
+
# but ActiveModel::Attributes calls super without arguments,
|
|
8
|
+
# which would call the original initialize method without arguments and raise an error.
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'enumy/enum'
|
|
2
|
+
require 'enumy/errors'
|
|
3
|
+
|
|
4
|
+
module Enumy
|
|
5
|
+
module Rails
|
|
6
|
+
module Model
|
|
7
|
+
def has_enum(name, class_name: name, **options)
|
|
8
|
+
enum_class = class_name.to_s.classify.safe_constantize
|
|
9
|
+
|
|
10
|
+
assert_valid_enum_type!(enum_class, class_name)
|
|
11
|
+
define_enum_attributes(name, enum_class, default: options[:default])
|
|
12
|
+
define_enum_validations(name, enum_class) unless options[:optional]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def define_enum_attributes(name, enum_class, **options)
|
|
18
|
+
attribute name, ActiveModel::Type::Enum.new(enum_class), default: -> { options[:default] }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def define_enum_validations(name, enum_class)
|
|
22
|
+
validates name, presence: true, inclusion: { in: enum_class.all }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def assert_valid_enum_type!(enum_class, class_name)
|
|
26
|
+
if enum_class.nil?
|
|
27
|
+
raise Errors::InvalidEnumClassError, "Could not resolve class `#{class_name.to_s.classify}`"
|
|
28
|
+
elsif !enum_class.ancestors.include?(Enumy::Enum)
|
|
29
|
+
raise Errors::InvalidEnumClassError, "`#{enum_class.name}` does not inherit from `#{Enumy::Enum.name}`"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/enumy/rails/railtie.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module Enumy
|
|
2
|
-
class Railtie < Rails::Railtie
|
|
2
|
+
class Railtie < ::Rails::Railtie
|
|
3
3
|
initializer "enumy.register_active_job_serializer" do |app|
|
|
4
|
-
if Rails::VERSION::MAJOR >= 6
|
|
5
|
-
require 'enumy/active_job/serializers/enum_serializer'
|
|
6
|
-
app.config.active_job.custom_serializers << Enumy::ActiveJob::Serializers::EnumSerializer
|
|
4
|
+
if ::Rails::VERSION::MAJOR >= 6
|
|
5
|
+
require 'enumy/rails/active_job/serializers/enum_serializer'
|
|
6
|
+
app.config.active_job.custom_serializers << Enumy::Rails::ActiveJob::Serializers::EnumSerializer
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
end
|
data/lib/enumy/version.rb
CHANGED
data/lib/enumy.rb
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
require 'enumy/version'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
require 'enumy/base'
|
|
5
|
-
end
|
|
2
|
+
require 'enumy/enum'
|
|
3
|
+
require 'enumy/model'
|
|
6
4
|
|
|
7
5
|
if defined?(Rails)
|
|
8
|
-
require 'enumy/
|
|
9
|
-
require 'enumy/
|
|
10
|
-
require 'enumy/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
require 'enumy/rails/railtie'
|
|
14
|
-
end
|
|
6
|
+
require 'enumy/rails/enum'
|
|
7
|
+
require 'enumy/rails/model'
|
|
8
|
+
require 'enumy/rails/generators/enumy/install/install_generator'
|
|
9
|
+
require 'enumy/rails/active_model/type/enum'
|
|
10
|
+
require 'enumy/rails/railtie'
|
|
15
11
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: enumy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bevan Holborn
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rake
|
|
@@ -53,28 +52,28 @@ dependencies:
|
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
53
|
version: '7.0'
|
|
55
54
|
description: Use Enumeration objects as ActiveRecord like associations
|
|
56
|
-
email:
|
|
57
55
|
executables: []
|
|
58
56
|
extensions: []
|
|
59
57
|
extra_rdoc_files: []
|
|
60
58
|
files:
|
|
61
59
|
- lib/enumy.rb
|
|
62
|
-
- lib/enumy/
|
|
63
|
-
- lib/enumy/active_model/type/enum.rb
|
|
64
|
-
- lib/enumy/base.rb
|
|
60
|
+
- lib/enumy/enum.rb
|
|
65
61
|
- lib/enumy/errors.rb
|
|
66
|
-
- lib/enumy/generators/enumy/install/install_generator.rb
|
|
67
|
-
- lib/enumy/generators/enumy/install/templates/app/enums/application_enum.rb
|
|
68
62
|
- lib/enumy/model.rb
|
|
63
|
+
- lib/enumy/rails/active_job/serializers/enum_serializer.rb
|
|
64
|
+
- lib/enumy/rails/active_model/type/enum.rb
|
|
65
|
+
- lib/enumy/rails/enum.rb
|
|
66
|
+
- lib/enumy/rails/generators/enumy/install/install_generator.rb
|
|
67
|
+
- lib/enumy/rails/generators/enumy/install/templates/app/enums/application_enum.rb
|
|
68
|
+
- lib/enumy/rails/initializer_interceptor.rb
|
|
69
|
+
- lib/enumy/rails/model.rb
|
|
69
70
|
- lib/enumy/rails/railtie.rb
|
|
70
|
-
- lib/enumy/test_helpers.rb
|
|
71
71
|
- lib/enumy/version.rb
|
|
72
72
|
homepage: https://rubygems.org/gems/enumy
|
|
73
73
|
licenses:
|
|
74
74
|
- MIT
|
|
75
75
|
metadata:
|
|
76
76
|
source_code_uri: https://gitlab.com/BevanHolborn/enumy
|
|
77
|
-
post_install_message:
|
|
78
77
|
rdoc_options: []
|
|
79
78
|
require_paths:
|
|
80
79
|
- lib
|
|
@@ -89,8 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
89
88
|
- !ruby/object:Gem::Version
|
|
90
89
|
version: '0'
|
|
91
90
|
requirements: []
|
|
92
|
-
rubygems_version: 3.
|
|
93
|
-
signing_key:
|
|
91
|
+
rubygems_version: 3.6.9
|
|
94
92
|
specification_version: 4
|
|
95
93
|
summary: ActiveRecord like enum associations
|
|
96
94
|
test_files: []
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
require 'enumy/base.rb'
|
|
2
|
-
|
|
3
|
-
module Enumy
|
|
4
|
-
module ActiveJob
|
|
5
|
-
module Serializers
|
|
6
|
-
class EnumSerializer < ::ActiveJob::Serializers::ObjectSerializer
|
|
7
|
-
|
|
8
|
-
def serialize(enum)
|
|
9
|
-
super({ class: enum.class.name, key: enum.key.to_s })
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def deserialize(hash)
|
|
13
|
-
hash[:class].constantize.find_by_key(hash[:key])
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def serialize?(value)
|
|
17
|
-
value.is_a?(klass)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def klass
|
|
23
|
-
Enumy::Base
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
module Enumy
|
|
2
|
-
module ActiveModel
|
|
3
|
-
module Type
|
|
4
|
-
class Enum < ::ActiveModel::Type::Value
|
|
5
|
-
def initialize(enum_class)
|
|
6
|
-
@enum_class = enum_class
|
|
7
|
-
super()
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def cast(value)
|
|
11
|
-
value.is_a?(@enum_class) ? value : @enum_class.find_by_key(value&.to_sym)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def serialize(value)
|
|
15
|
-
if value.is_a?(@enum_class)
|
|
16
|
-
value.key.to_s
|
|
17
|
-
else
|
|
18
|
-
@enum_class.find_by_key(value&.to_sym) ? value&.to_s : nil
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def deserialize(value)
|
|
23
|
-
value.is_a?(@enum_class) ? value : @enum_class.find_by_key(value&.to_sym)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def type
|
|
27
|
-
:enum
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
data/lib/enumy/base.rb
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
require_relative 'errors'
|
|
2
|
-
|
|
3
|
-
module Enumy
|
|
4
|
-
class Base
|
|
5
|
-
include ::ActiveModel::Model
|
|
6
|
-
include ::ActiveModel::Attributes
|
|
7
|
-
|
|
8
|
-
attribute :key
|
|
9
|
-
|
|
10
|
-
def initialize(key, **attrs)
|
|
11
|
-
raise ArgumentError, "#{self.class.name.upcase} enum requires a `key`" if key.nil?
|
|
12
|
-
key = key.to_sym
|
|
13
|
-
|
|
14
|
-
super(key: key, **attrs)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def human_attribute_name(attribute)
|
|
18
|
-
I18n.t("#{self.class.i18n_scope}.attributes.models.#{self.class.model_name.i18n_key}/#{self.key}.#{attribute}")
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def name
|
|
22
|
-
human_attribute_name(:key)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def titleize
|
|
26
|
-
key.to_s.titleize
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def to_s
|
|
30
|
-
key.to_s
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def inspect
|
|
34
|
-
"#<#{self.class.name} #{attributes.map { |name, value| "#{name}: #{value.inspect}" }.join(', ')}>"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
class << self
|
|
38
|
-
|
|
39
|
-
def define(enum)
|
|
40
|
-
raise ArgumentError, "Expected an object of type `Enumy::Base`, got #{enum.class.name}" unless enum.is_a?(Enumy::Base)
|
|
41
|
-
|
|
42
|
-
if instances[enum.key]
|
|
43
|
-
raise Errors::DuplicateEnumInstanceError, "Enum `#{enum.key.to_s.upcase}` is using a duplicate key `#{enum.key}` for Enum '#{enum.class.name}'."
|
|
44
|
-
else
|
|
45
|
-
instances[enum.key] = enum
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def all
|
|
50
|
-
instances.values
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def find(key)
|
|
54
|
-
find_by_key(key) || raise(Errors::EnumNotFoundError.new("Could not find a `#{self.name}` enum with a `key` of #{key}"))
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def find_by_key(key)
|
|
58
|
-
key = key.to_sym if key.is_a?(String)
|
|
59
|
-
instances[key]
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def find_by(**args)
|
|
63
|
-
raise ArgumentError, "`find_by` requires at least one key-value pair" if args.empty?
|
|
64
|
-
|
|
65
|
-
instances.values.find do |instance|
|
|
66
|
-
args.all? { |attr, value| instance.send(attr) == value }
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def model_name
|
|
71
|
-
@model_name ||= ::ActiveModel::Name.new(self, nil, self.name.to_s)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def i18n_scope
|
|
75
|
-
:enum
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
private
|
|
79
|
-
|
|
80
|
-
def instances
|
|
81
|
-
@instances ||= {}
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
end
|
|
87
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
require "rails/generators"
|
|
2
|
-
|
|
3
|
-
module Enumy
|
|
4
|
-
module Generators
|
|
5
|
-
class InstallGenerator < Rails::Generators::Base
|
|
6
|
-
source_root File.expand_path("templates", __dir__)
|
|
7
|
-
|
|
8
|
-
def copy_application_enum
|
|
9
|
-
template "app/enums/application_enum.rb", "app/enums/application_enum.rb"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def add_application_record_concern
|
|
13
|
-
inject_into_file "app/models/application_record.rb", after: /^.*primary_abstract_class.*$/ do
|
|
14
|
-
<<~CODE
|
|
15
|
-
|
|
16
|
-
\textend Enumy::Model\n
|
|
17
|
-
CODE
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
data/lib/enumy/test_helpers.rb
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
module Enumy
|
|
2
|
-
module TestHelpers
|
|
3
|
-
def with_enum_defined(enum_class, enum_instance)
|
|
4
|
-
enum_class.define(enum_instance)
|
|
5
|
-
|
|
6
|
-
yield
|
|
7
|
-
|
|
8
|
-
enum_class.send(:instances).delete(enum_instance.key)
|
|
9
|
-
enum_const_name = enum_class.constants.find { |const_name| enum_class.const_get(const_name) == enum_instance }
|
|
10
|
-
remove_const(enum_const_name) if enum_const_name
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def enum_model_class(&block)
|
|
14
|
-
base_class = Class.new(ApplicationRecord) do
|
|
15
|
-
extend Enumy::Model
|
|
16
|
-
|
|
17
|
-
class << self
|
|
18
|
-
def name
|
|
19
|
-
"TempModel"
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
base_class.class_exec(&block) if block
|
|
25
|
-
base_class
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|