enumy 0.6.0 → 0.7.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 +60 -0
- data/lib/enumy/errors.rb +6 -0
- 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/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/rails_enum.rb +41 -0
- data/lib/enumy/version.rb +1 -1
- data/lib/enumy.rb +6 -11
- metadata +11 -14
- 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/model.rb +0 -32
- 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: 6dd6a6b997ce941c0d25307a6d58dacbbf37fe400599138b5e5bf19368a50e79
|
|
4
|
+
data.tar.gz: 333f8abf304d49f44cb298a73cb9aea1a5e35a12727156ec79a1d8edcbb5f126
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 538a40ecabc8d6268a219360af3cbd5c0204b38eb22914ce721c16f7c7b98f14e3738b8714357c7c47ac4b3abda05befd31f53d3dd0b2ed4c94e07bcbde86343
|
|
7
|
+
data.tar.gz: 1e286b730ff740ce7e04ac2d6c1bbd74918002da2ea5a2ee5c75379e5d0c29e3d7b4ed59fffc59152797cf9b36390fd6db61f41c51353eb86e8f39dedde75998
|
data/lib/enumy/enum.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
"#<#{self.class.name} #{attributes.map { |name, value| "#{name}: #{value.inspect}" }.join(', ')}>"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
|
|
23
|
+
def define(enum)
|
|
24
|
+
raise ArgumentError, "Expected an object of type `Enumy::Enum`, got #{enum.class.name}" unless enum.is_a?(Enumy::Enum)
|
|
25
|
+
|
|
26
|
+
if instances[enum.key]
|
|
27
|
+
raise Errors::DuplicateEnumInstanceError, "Enum `#{enum.key.to_s.upcase}` is using a duplicate key `#{enum.key}` for Enum '#{enum.class.name}'."
|
|
28
|
+
else
|
|
29
|
+
instances[enum.key] = enum
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def all
|
|
34
|
+
instances.values
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def find(key)
|
|
38
|
+
find_by(key: key) || raise(Errors::EnumNotFoundError.new("Could not find a `#{self.name}` enum with a `key` of #{key}"))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def find_by(**args)
|
|
42
|
+
raise ArgumentError, "`find_by` requires at least one key-value pair" if args.empty?
|
|
43
|
+
|
|
44
|
+
instances.values.find do |instance|
|
|
45
|
+
args.all? do |attr, value|
|
|
46
|
+
instance.send(attr) == value
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def instances
|
|
54
|
+
@instances ||= {}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
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
|
|
@@ -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,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::Base.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
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'enumy/rails/initializer_interceptor'
|
|
2
|
+
|
|
3
|
+
module Enumy
|
|
4
|
+
class RailsEnum < Enumy::Enum
|
|
5
|
+
include Enumy::Rails::InitializerInterceptor
|
|
6
|
+
include ::ActiveModel::Model
|
|
7
|
+
include ::ActiveModel::Attributes
|
|
8
|
+
|
|
9
|
+
attribute :key
|
|
10
|
+
|
|
11
|
+
def initialize(key, **attrs)
|
|
12
|
+
raise Errors::KeyMissingError.new(self) if key.nil?
|
|
13
|
+
super(key: key.to_sym, **attrs)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def titleize
|
|
17
|
+
key.to_s.titleize
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def human_attribute_name(attribute)
|
|
21
|
+
I18n.t("#{self.class.i18n_scope}.attributes.models.#{self.class.model_name.i18n_key}/#{self.key}.#{attribute}")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def name
|
|
25
|
+
human_attribute_name(:key)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
|
|
30
|
+
def model_name
|
|
31
|
+
@model_name ||= ::ActiveModel::Name.new(self, nil, self.name.to_s)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def i18n_scope
|
|
35
|
+
:enum
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/enumy/version.rb
CHANGED
data/lib/enumy.rb
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
require 'enumy/version'
|
|
2
|
-
|
|
3
|
-
if defined?(ActiveModel)
|
|
4
|
-
require 'enumy/base'
|
|
5
|
-
end
|
|
2
|
+
require 'enumy/enum'
|
|
6
3
|
|
|
7
4
|
if defined?(Rails)
|
|
8
|
-
require 'enumy/
|
|
9
|
-
require 'enumy/
|
|
10
|
-
require 'enumy/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
require 'enumy/rails/railtie'
|
|
14
|
-
end
|
|
5
|
+
require 'enumy/rails_enum'
|
|
6
|
+
require 'enumy/rails/model'
|
|
7
|
+
require 'enumy/rails/generators/enumy/install/install_generator'
|
|
8
|
+
require 'enumy/rails/active_model/type/enum'
|
|
9
|
+
require 'enumy/rails/railtie'
|
|
15
10
|
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.7.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,27 @@ 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/
|
|
67
|
-
- lib/enumy/
|
|
68
|
-
- lib/enumy/
|
|
62
|
+
- lib/enumy/rails/active_job/serializers/enum_serializer.rb
|
|
63
|
+
- lib/enumy/rails/active_model/type/enum.rb
|
|
64
|
+
- lib/enumy/rails/generators/enumy/install/install_generator.rb
|
|
65
|
+
- lib/enumy/rails/generators/enumy/install/templates/app/enums/application_enum.rb
|
|
66
|
+
- lib/enumy/rails/initializer_interceptor.rb
|
|
67
|
+
- lib/enumy/rails/model.rb
|
|
69
68
|
- lib/enumy/rails/railtie.rb
|
|
70
|
-
- lib/enumy/
|
|
69
|
+
- lib/enumy/rails_enum.rb
|
|
71
70
|
- lib/enumy/version.rb
|
|
72
71
|
homepage: https://rubygems.org/gems/enumy
|
|
73
72
|
licenses:
|
|
74
73
|
- MIT
|
|
75
74
|
metadata:
|
|
76
75
|
source_code_uri: https://gitlab.com/BevanHolborn/enumy
|
|
77
|
-
post_install_message:
|
|
78
76
|
rdoc_options: []
|
|
79
77
|
require_paths:
|
|
80
78
|
- lib
|
|
@@ -89,8 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
89
87
|
- !ruby/object:Gem::Version
|
|
90
88
|
version: '0'
|
|
91
89
|
requirements: []
|
|
92
|
-
rubygems_version: 3.
|
|
93
|
-
signing_key:
|
|
90
|
+
rubygems_version: 3.6.9
|
|
94
91
|
specification_version: 4
|
|
95
92
|
summary: ActiveRecord like enum associations
|
|
96
93
|
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/model.rb
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
require_relative 'base'
|
|
2
|
-
require_relative 'errors'
|
|
3
|
-
|
|
4
|
-
module Enumy
|
|
5
|
-
module Model
|
|
6
|
-
def has_enum(name, class_name: name, **options)
|
|
7
|
-
enum_class = class_name.to_s.classify.safe_constantize
|
|
8
|
-
|
|
9
|
-
assert_valid_enum_type!(enum_class, class_name)
|
|
10
|
-
define_enum_attributes(name, enum_class, default: options[:default])
|
|
11
|
-
define_enum_validations(name, enum_class) unless options[:optional]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def define_enum_attributes(name, enum_class, **options)
|
|
17
|
-
attribute name, ActiveModel::Type::Enum.new(enum_class), default: -> { options[:default] }
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def define_enum_validations(name, enum_class)
|
|
21
|
-
validates name, presence: true, inclusion: { in: enum_class.all }
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def assert_valid_enum_type!(enum_class, class_name)
|
|
25
|
-
if enum_class.nil?
|
|
26
|
-
raise Errors::InvalidEnumClassError, "Could not resolve class `#{class_name.to_s.classify}`"
|
|
27
|
-
elsif !enum_class.ancestors.include?(Enumy::Base)
|
|
28
|
-
raise Errors::InvalidEnumClassError, "`#{enum_class.name}` does not inherit from `#{Enumy::Base.name}`"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
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
|