enummer 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3876abd550e7a6cc2a44853daff2124bcaf7d277c9202d017b93d1f71a9b3223
4
- data.tar.gz: 0ce455ff89be35d0aa8324570d33a5f4039ae4b3fdd7d67b317192d7bad60c21
3
+ metadata.gz: 3c5046553ca9c053f2632d3bc1ca202a9c8da4b1d93fdca16c5d35606e774932
4
+ data.tar.gz: 06651c73f0aacb682d4a8dbb7b22387504eb2e6f6bc02d6de7dec88ef41605b7
5
5
  SHA512:
6
- metadata.gz: b54ffad39435c24dcc57cf27914cdcf895be71333d2665ce553775fd39bb51e1ae6b986b25adb3dd52ff19e50319a402fa8e5ff994605fccca74ceb52fba1e63
7
- data.tar.gz: 876a285e2de4701cef2fa2cf66e36d4d9ae560fb0951686392ad7b2fcbb7458a3ed4b9205742a55b55a3ecf4e39ed86e7816a16b07d1c9786a4cc43f4030913e
6
+ metadata.gz: e11ec3eabc2ede11eb342fc5022ef48c3905a338180ce925452d36baed39597a351fe183494e4ae18a3e63e2956e61a2cf7439d85111f08d8a3a5712d9cddf49
7
+ data.tar.gz: 7fa79d2c2d7743ab75c26c1754aa010894bfb99314869118e075f663ac33511b435c9200d360c16ddcb0fba55c21600a28c5b0076e75fb323dc6727dc9bb8690
data/README.md CHANGED
@@ -33,6 +33,18 @@ Now set up enummer with the available values in your model:
33
33
  enummer permissions: %i[read write execute]
34
34
  ```
35
35
 
36
+ Similar to `enum`, enummer can also be initialized with a hash, where the numeric index represents the position of the bit that maps to the flag:
37
+
38
+ ``` ruby
39
+ enummer permissions: {
40
+ read: 0,
41
+ write: 1,
42
+ execute: 2
43
+ }
44
+ ```
45
+
46
+ This makes it easier to add/remove entries without worrying about migrating historical data.
47
+
36
48
  ### Scopes
37
49
 
38
50
  Scopes will now be provided for `<option>` and `not_<option>`.
@@ -4,17 +4,16 @@ require "active_record/type"
4
4
 
5
5
  module Enummer
6
6
  class EnummerType < ::ActiveRecord::Type::Value
7
- # @param [Array<Symbol>] value_names list of all possible values for this type
8
- def initialize(value_names:)
9
- @value_names = value_names
10
- @bit_pairs = determine_bit_pairs(value_names)
7
+ # @param [Array<Symbol>] values hash with bit-value pairs for all possible values for this type
8
+ def initialize(values:)
9
+ @values = values
11
10
  end
12
11
 
13
12
  # @return Symbol Representation of this type
14
13
  # @example
15
14
  # :enummer[read|write|execute]
16
15
  def type
17
- "enummer[#{@value_names.join("|")}]".to_sym
16
+ :"enummer[#{@values.keys.join("|")}]"
18
17
  end
19
18
 
20
19
  # @param [Symbol|Array<Symbol>] value Current value represented as one or more symbols
@@ -22,7 +21,7 @@ module Enummer
22
21
  def serialize(value)
23
22
  return unless value
24
23
 
25
- Array.wrap(value).sum { |value_name| @bit_pairs.fetch(value_name.to_sym, 0) }
24
+ Array.wrap(value).sum { |value_name| @values.fetch(value_name, 0) }
26
25
  end
27
26
 
28
27
  # @param [Numeric] value Numeric representation of values
@@ -31,19 +30,17 @@ module Enummer
31
30
  return [] unless value
32
31
  return [] if value.to_i.zero?
33
32
 
34
- @bit_pairs.each_with_object([]) do |(pair_name, pair_value), value_names|
33
+ @values.each_with_object([]) do |(pair_name, pair_value), value_names|
35
34
  next if (value & pair_value).zero?
36
35
 
37
36
  value_names << pair_name
38
37
  end
39
38
  end
40
39
 
41
- private
42
-
43
- def determine_bit_pairs(value_names)
44
- value_names.map.with_index do |name, shift|
45
- [name, 1 << shift]
46
- end.to_h
40
+ # @param [Array<Symbol>] value Current value represented as one or more symbols or strings
41
+ # @return [Array<Symbol>] Current value represented as symbols
42
+ def cast(value)
43
+ Array.wrap(value).map(&:to_sym)
47
44
  end
48
45
  end
49
46
  end
@@ -13,10 +13,11 @@ module Enummer
13
13
  options[:_suffix] = values.delete(:_suffix)
14
14
 
15
15
  name, values = values.first
16
+ values = _enummer_determine_bit_pairs(values)
16
17
 
17
- attribute(name, :enummer, value_names: values)
18
+ attribute(name, :enummer, values: values)
18
19
 
19
- singleton_class.__send__(:define_method, name) { values }
20
+ singleton_class.__send__(:define_method, name) { values.keys }
20
21
 
21
22
  _enummer_build_with_scope(name, values)
22
23
  _enummer_build_values(name, values, options)
@@ -24,20 +25,20 @@ module Enummer
24
25
 
25
26
  private
26
27
 
27
- def _enummer_build_with_scope(attribute_name, value_names)
28
+ def _enummer_build_with_scope(attribute_name, values)
28
29
  scope "with_#{attribute_name}", lambda { |desired|
29
- expected = Array.wrap(desired).sum(0) { |value| 1 << value_names.index(value) }
30
+ expected = Array.wrap(desired).sum(0) { |value| values[value.to_sym] }
30
31
 
31
32
  where("#{attribute_name} & :expected = :expected", expected: expected)
32
33
  }
33
34
  end
34
35
 
35
- def _enummer_build_values(attribute_name, value_names, options)
36
- value_names.each_with_index do |name, i|
36
+ def _enummer_build_values(attribute_name, values, options)
37
+ values.each do |name, bit|
37
38
  method_name = _enummer_method_name(attribute_name, name, options)
38
39
 
39
- define_method("#{method_name}?") { self[attribute_name].include?(name) }
40
- define_method("#{method_name}=") do |new_value|
40
+ define_method(:"#{method_name}?") { self[attribute_name].include?(name) }
41
+ define_method(:"#{method_name}=") do |new_value|
41
42
  if ActiveModel::Type::Boolean.new.cast(new_value)
42
43
  self[attribute_name] += [name]
43
44
  else
@@ -45,12 +46,10 @@ module Enummer
45
46
  end
46
47
  self[attribute_name].uniq!
47
48
  end
48
- define_method("#{method_name}!") do
49
+ define_method(:"#{method_name}!") do
49
50
  update(attribute_name => self[attribute_name] + [name])
50
51
  end
51
52
 
52
- bit = 1 << i
53
-
54
53
  scope method_name, -> { where("#{attribute_name} & :bit = :bit", bit: bit) }
55
54
  scope "not_#{method_name}", -> { where("#{attribute_name} & :bit != :bit", bit: bit) }
56
55
  end
@@ -69,5 +68,12 @@ module Enummer
69
68
 
70
69
  value
71
70
  end
71
+
72
+ def _enummer_determine_bit_pairs(values)
73
+ values = values.map.with_index { |value, i| [value, i] }.to_h if values.is_a?(Array)
74
+ values.transform_values do |shift|
75
+ 1 << shift
76
+ end
77
+ end
72
78
  end
73
79
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Enummer
4
- VERSION = "1.0.4"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # desc "Explaining what the task does"
3
4
  # task :enummer do
4
5
  # # Task goes here
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enummer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamie Schembri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-08 00:00:00.000000000 Z
11
+ date: 2024-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -55,14 +55,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
55
55
  requirements:
56
56
  - - ">="
57
57
  - !ruby/object:Gem::Version
58
- version: '2.7'
58
+ version: '3.1'
59
59
  required_rubygems_version: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - ">="
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  requirements: []
65
- rubygems_version: 3.5.4
65
+ rubygems_version: 3.5.9
66
66
  signing_key:
67
67
  specification_version: 4
68
68
  summary: Multi-value enums for Rails.