enum_ish 1.4.1 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34d21d01c11cb32143d1ce656228165fc93059f820b60f2cc109668a61e70680
4
- data.tar.gz: a26baa4da8d0ae6e5ad1dce8cdf169f24fbe79ec8ddc88acf5fb2180db817b6f
3
+ metadata.gz: 2536b44ce0b10dedf1ffb032c15d9198a45837b9dc9cacda64ef3e1694810f92
4
+ data.tar.gz: b51a0ed47f636aebc806cba78f7cc9fadd003b60c09ace3fd29e85a3cf29fb65
5
5
  SHA512:
6
- metadata.gz: cc05a7517f723a1df0f521e031d2c171ed6a3ad0614974326c52464ce5ecf7f89b5e591f0da34a15fac70212ab44ab883f64b7dff45b67ba865c153c2ebd3dd9
7
- data.tar.gz: 8cb363ef8d2f7988dee963d3baef608b076484afa46268f1d08a7b21fe5ef12c736d09cb05ba3e6efaa01ce8b6acbf85f0748aef6d39a407338b499aa94f22c4
6
+ metadata.gz: 2be96b86a6286d62b357c73420fe65d63a990f84dbbebf044eac6adc9ea5a662a5f97aa44b43cfdce02717f4fa8019a98e9bfb180c2447bce19812b13e02b93e
7
+ data.tar.gz: e1339bf571d9a80658c2b5a108f7722af0b0d6f4e4196e28e7a083dd87b56700faf42ac1d09001b9ff03a52fefdb73302f66f1f9d72a61a15418e33c85f79fce
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.5.0
4
+
5
+ * Add dictionary cache feature.
6
+ * Change module inclusion. Use 'include EnumIsh::Base' instead of 'extend EnumIsh'.
7
+ * Move configuration method to `EnumIsh`. Use `EnumIsh.configure` instead of 'EnumIsh::Config.configure'.
8
+
3
9
  ## 1.4.1
4
10
 
5
11
  * Avoid overwrite of superclass's `_enum_ish_enums`.
data/README.md CHANGED
@@ -26,7 +26,7 @@ Extend your class using EnumIsh and define an enum-like field:
26
26
 
27
27
  ```ruby
28
28
  class User
29
- extend EnumIsh
29
+ include EnumIsh::Base
30
30
  attr_accessor :status # status is a string field
31
31
  enum_ish :status, ['enable', 'disable'] # status has 'enable' or 'disable'
32
32
  end
@@ -82,7 +82,7 @@ Set default value:
82
82
 
83
83
  ```ruby
84
84
  class User
85
- extend EnumIsh
85
+ include EnumIsh::Base
86
86
  attr_accessor :status
87
87
  enum_ish :status, ['enable', 'disable'], default: 'enable'
88
88
  end
@@ -95,7 +95,7 @@ Use default value with block:
95
95
 
96
96
  ```ruby
97
97
  class User
98
- extend EnumIsh
98
+ include EnumIsh::Base
99
99
  attr_accessor :status, :flag
100
100
  enum_ish :status, ['enable', 'disable'], default: -> { flag ? 'enable' : 'disable' }
101
101
  end
@@ -110,7 +110,7 @@ Generate predicate methods:
110
110
 
111
111
  ```ruby
112
112
  class User
113
- extend EnumIsh
113
+ include EnumIsh::Base
114
114
  attr_accessor :status
115
115
  enum_ish :status, ['enable', 'disable'], predicate: true
116
116
  end
@@ -125,7 +125,7 @@ Without prefix:
125
125
 
126
126
  ```ruby
127
127
  class User
128
- extend EnumIsh
128
+ include EnumIsh::Base
129
129
  attr_accessor :status
130
130
  enum_ish :status, ['enable', 'disable'], predicate: { prefix: false }
131
131
  end
@@ -142,7 +142,7 @@ Generate getter and setter for aliased symbols instead of raw values:
142
142
 
143
143
  ```ruby
144
144
  class User
145
- extend EnumIsh
145
+ include EnumIsh::Base
146
146
  attr_accessor :status
147
147
  enum_ish :status, { _enable: 'enable', _disable: 'disable' }, accessor: true
148
148
  end
@@ -161,7 +161,7 @@ Generate accessor:
161
161
 
162
162
  ```ruby
163
163
  class User < ActiveRecord::Base
164
- extend EnumIsh
164
+ include EnumIsh::Base
165
165
  enum_ish :status, { _enable: 'enable', _disable: 'disable' }, accessor: true
166
166
  end
167
167
 
@@ -174,7 +174,7 @@ Generate scope:
174
174
 
175
175
  ```ruby
176
176
  class User < ActiveRecord::Base
177
- extend EnumIsh
177
+ include EnumIsh::Base
178
178
  enum_ish :status, ['enable', 'disable'], scope: true
179
179
  end
180
180
 
@@ -188,7 +188,7 @@ Generate validation:
188
188
 
189
189
  ```ruby
190
190
  class User < ActiveRecord::Base
191
- extend EnumIsh
191
+ include EnumIsh::Base
192
192
  enum_ish :status, ['enable', 'disable'], validate: true
193
193
  end
194
194
 
@@ -197,6 +197,17 @@ user.status = 'INVALID'
197
197
  user.valid? #=> false
198
198
  ```
199
199
 
200
+ ### Dictionary cache
201
+
202
+ You can enable dictionary cache using rack middleware:
203
+
204
+ ```ruby
205
+ Rails.application.config.middleware.use EnumIsh::DictionaryCache
206
+ ```
207
+
208
+ This middleware enables dictionary cache for each request.
209
+ Prformance of dictionary lookup will be improved in case one dictionary is used repeatedly in the same request.
210
+
200
211
  ## Contributing
201
212
 
202
213
  Bug reports and pull requests are welcome at https://github.com/kanety/enum_ish.
data/lib/enum_ish.rb CHANGED
@@ -1,36 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support'
2
4
  require 'enum_ish/version'
3
- require 'enum_ish/errors'
4
5
  require 'enum_ish/config'
5
- require 'enum_ish/enum'
6
- require 'enum_ish/dictionary'
7
- require 'enum_ish/definer'
8
- require 'enum_ish/active_record_definer' if defined?(ActiveRecord::Base)
6
+ require 'enum_ish/base'
7
+ require 'enum_ish/dictionary_cache'
9
8
 
10
9
  module EnumIsh
11
- def enum_ish(name, map, config = {})
12
- enum = Enum.new(name, map, config)
13
-
14
- self._enum_ish_enums ||= {}
15
- self._enum_ish_enums[name.to_sym] = enum
16
-
17
- if defined?(ActiveRecord::Base) && self.ancestors.include?(ActiveRecord::Base)
18
- ActiveRecordDefiner.new(self).define(enum)
19
- else
20
- Definer.new(self).define(enum)
10
+ class << self
11
+ def configure
12
+ yield Config
21
13
  end
22
- end
23
-
24
- def self.extended(klass)
25
- super
26
- klass.class_attribute :_enum_ish_enums
27
- klass.extend ClassMethods
28
- end
29
14
 
30
- module ClassMethods
31
- def inherited(subclass)
32
- super
33
- subclass._enum_ish_enums = self._enum_ish_enums.dup
15
+ def config
16
+ Config
34
17
  end
35
18
  end
36
19
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'active_record_enum_type'
2
4
 
3
5
  module EnumIsh
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EnumIsh
2
4
  class ActiveRecordEnumType < ActiveRecord::Type::Value
3
5
  def initialize(name, mapping, subtype)
@@ -0,0 +1,29 @@
1
+ require_relative 'enum'
2
+ require_relative 'dictionary'
3
+ require_relative 'errors'
4
+ require_relative 'definer'
5
+ require_relative 'active_record_definer' if defined?(ActiveRecord::Base)
6
+
7
+ module EnumIsh
8
+ module Base
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ class_attribute :_enum_ish_enums
13
+ self._enum_ish_enums = {}
14
+ end
15
+
16
+ class_methods do
17
+ def enum_ish(name, map, config = {})
18
+ enum = Enum.new(name, map, config)
19
+ self._enum_ish_enums = _enum_ish_enums.merge(name.to_sym => enum)
20
+
21
+ if defined?(ActiveRecord::Base) && self.ancestors.include?(ActiveRecord::Base)
22
+ ActiveRecordDefiner.new(self).define(enum)
23
+ else
24
+ Definer.new(self).define(enum)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EnumIsh
2
4
  class Config
3
- @@options = {
5
+ class_attribute :data
6
+
7
+ self.data = {
4
8
  text_prefix: '',
5
9
  text_suffix: '_text',
6
10
  options_prefix: '',
@@ -11,19 +15,13 @@ module EnumIsh
11
15
  scope_suffix: ''
12
16
  }
13
17
 
14
- @@options.keys.each do |key|
18
+ data.keys.each do |key|
15
19
  define_singleton_method "#{key}" do
16
- @@options[key]
20
+ data[key]
17
21
  end
18
22
 
19
23
  define_singleton_method "#{key}=" do |val|
20
- @@options[key] = val
21
- end
22
- end
23
-
24
- class << self
25
- def configure
26
- yield self
24
+ data[key] = val
27
25
  end
28
26
  end
29
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EnumIsh
2
4
  class Definer
3
5
  def initialize(klass)
@@ -1,10 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EnumIsh
2
4
  class Dictionary
5
+ CACHE_KEY = :_enum_ish_dictionary_cache
6
+
3
7
  def initialize(klass, enum, options = {})
4
8
  @klass = klass
5
9
  @enum = enum
6
10
  @options = options
7
- @dict = load_dict
11
+ @dict = cache { Lookup.new(@klass, @enum, @options).call }
8
12
  end
9
13
 
10
14
  def translate_value(value)
@@ -21,8 +25,36 @@ module EnumIsh
21
25
 
22
26
  private
23
27
 
24
- def load_dict
25
- i18n = load_from_i18n.transform_keys { |k| k.to_s.to_sym }
28
+ def cache
29
+ if (cache = Thread.current[CACHE_KEY]) != nil
30
+ cache[I18n.locale] ||= {}
31
+ cache[I18n.locale][@klass] ||= {}
32
+ cache[I18n.locale][@klass][@enum] ||= {}
33
+ cache[I18n.locale][@klass][@enum][@optons] ||= yield
34
+ else
35
+ yield
36
+ end
37
+ end
38
+
39
+ class << self
40
+ def cache
41
+ Thread.current[CACHE_KEY] = {}
42
+ yield
43
+ ensure
44
+ Thread.current[CACHE_KEY] = nil
45
+ end
46
+ end
47
+ end
48
+
49
+ class Lookup
50
+ def initialize(klass, enum, options = {})
51
+ @klass = klass
52
+ @enum = enum
53
+ @options = options
54
+ end
55
+
56
+ def call
57
+ i18n = lookup_for(@klass).transform_keys { |k| k.to_s.to_sym }
26
58
 
27
59
  dict = {}
28
60
  if @enum.setting[:accessor]
@@ -34,27 +66,19 @@ module EnumIsh
34
66
  filter(dict)
35
67
  end
36
68
 
37
- def load_from_i18n
69
+ private
70
+
71
+ def lookup_for(klass)
38
72
  key = [@enum.name, @options[:format]].compact.join('/')
39
73
  options = (@options[:i18n_options] || {}).merge(default: nil)
40
- dict = I18n.t(:"enum_ish.#{@klass.name.underscore}.#{key}", **options)
41
- return dict if dict
42
74
 
43
- i18n_ancestors.each do |ancestor|
44
- dict = I18n.t(:"enum_ish.#{ancestor.name.underscore}.#{key}", **options)
45
- return dict if dict
75
+ if klass.name.to_s.in?(['ActiveRecord::Base', 'Object'])
76
+ I18n.t(:"enum_ish.defaults.#{key}", **options) || @enum.mapping.invert
77
+ elsif klass.name.blank? || !klass.is_a?(Class)
78
+ resolve(klass.superclass)
79
+ else
80
+ I18n.t(:"enum_ish.#{klass.name.underscore}.#{key}", **options) || lookup_for(klass.superclass)
46
81
  end
47
-
48
- dict = I18n.t(:"enum_ish.defaults.#{key}", **options)
49
- return dict if dict
50
-
51
- @enum.mapping.invert
52
- end
53
-
54
- def i18n_ancestors
55
- @klass.ancestors.drop(1)
56
- .take_while { |a| a.name != 'ActiveRecord::Base' && a.name != 'Object' }
57
- .select { |a| a.is_a?(Class) && !a.name.empty? }
58
82
  end
59
83
 
60
84
  def filter(dict)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EnumIsh
4
+ class DictionaryCache
5
+ def initialize(app)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ EnumIsh::Dictionary.cache do
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/enum_ish/enum.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EnumIsh
2
4
  class Enum
3
5
  attr_accessor :name
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EnumIsh
2
4
  class Error < StandardError
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EnumIsh
2
- VERSION = '1.4.1'
4
+ VERSION = '1.5.0'
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enum_ish
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshikazu Kaneta
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-25 00:00:00.000000000 Z
11
+ date: 2021-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -118,9 +118,11 @@ files:
118
118
  - lib/enum_ish.rb
119
119
  - lib/enum_ish/active_record_definer.rb
120
120
  - lib/enum_ish/active_record_enum_type.rb
121
+ - lib/enum_ish/base.rb
121
122
  - lib/enum_ish/config.rb
122
123
  - lib/enum_ish/definer.rb
123
124
  - lib/enum_ish/dictionary.rb
125
+ - lib/enum_ish/dictionary_cache.rb
124
126
  - lib/enum_ish/enum.rb
125
127
  - lib/enum_ish/errors.rb
126
128
  - lib/enum_ish/version.rb