bitwise_attribute 0.2.2 → 0.3.4

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: 728afc2714df27029947e0f98b2c542ad8835bf44e052f720c588d22f2bcb821
4
- data.tar.gz: 5e8fe818d69624b1888f954416a15f9cf938039067a5f67fea12eef73bf76e31
3
+ metadata.gz: a19184eaf7a73f44c929b1aa3cb0794d2d4be1f54a5c15802e1cd1eb0edf1641
4
+ data.tar.gz: 03edbbb6992ec20733a349a7eefc7b776a4fa91c74e1373222b8949298bbc07f
5
5
  SHA512:
6
- metadata.gz: 257fb003a2eb0421a5ca03b5b6cd32a2b4317c7172cb26a204e2516bc9b7aeb07989a99867bb5f33bbb6ccc6667f7bd88d5e1c116b18f6d782eee9dd469c5ece
7
- data.tar.gz: 58b7153d9e3b51898d387252a1a91ed6f1514c778eff46f1941ed78cb4ff88b9d933131e493b4dbb184aaa27720d430335df741ba9a5ea103a66305b15d73a8e
6
+ metadata.gz: 9159f1439b717c6f4954ed5582d8811d4da7b37b3375ca1cfe4899760d94e5ca189f889180a5465a4b2dc18f7073aed55cfafb852acfce6c93d628088729c784
7
+ data.tar.gz: 2a2c1f64d74e7184c23d403f48b76566e34db91b2d1e081c70effad74394d4fb7e328c058cdadf6ec4945f4180ce6bedf7c2d2ffcabec69ef2890aee3b28ff10
@@ -0,0 +1,41 @@
1
+
2
+ name: CI
3
+
4
+ on: [push, pull_request]
5
+
6
+ jobs:
7
+ lint:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - uses: ruby/setup-ruby@v1
12
+ with:
13
+ ruby-version: "2.5"
14
+ bundler-cache: true
15
+ - name: rubocop version
16
+ timeout-minutes: 1
17
+ run: bundle exec rubocop --version
18
+ - name: rubocop
19
+ timeout-minutes: 5
20
+ run: bundle exec rubocop -c .rubocop.yml
21
+
22
+ test:
23
+ runs-on: ubuntu-latest
24
+ continue-on-error: ${{ matrix.experimental }}
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ ruby: ["2.5", "2.6", "2.7", "3.0"]
29
+ experimental: [false]
30
+ include:
31
+ - ruby: "truffleruby"
32
+ experimental: true
33
+ steps:
34
+ - uses: actions/checkout@v2
35
+ - uses: ruby/setup-ruby@v1
36
+ with:
37
+ ruby-version: ${{matrix.ruby}}
38
+ bundler-cache: true
39
+ - name: Run tests
40
+ timeout-minutes: 5
41
+ run: ${{matrix.env}} bundle exec rspec
data/.rspec CHANGED
@@ -1,4 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
3
  --require spec_helper
4
- --order random
4
+ --order rand
data/.rubocop.yml CHANGED
@@ -1,21 +1,34 @@
1
- Metrics/AbcSize:
2
- Max: 30
1
+ require:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ NewCops: enable
7
+ TargetRubyVersion: 2.5
8
+
9
+ RSpec/MultipleMemoizedHelpers:
10
+ Max: 10
3
11
 
4
12
  Style/Documentation:
5
- Exclude:
6
- - 'spec/**/*'
7
- - 'test/**/*'
8
- - 'lib/bitwise_attribute.rb'
9
- - 'lib/bitwise_attribute/values_list.rb'
13
+ Enabled: false
10
14
 
11
- Metrics/LineLength:
15
+ Layout/LineLength:
12
16
  Max: 100
13
17
 
18
+ Metrics/CyclomaticComplexity:
19
+ Max: 15
20
+
21
+ Metrics/PerceivedComplexity:
22
+ Max: 15
23
+
14
24
  Metrics/MethodLength:
15
- Max: 30
25
+ Max: 50
16
26
 
17
27
  Metrics/BlockLength:
18
28
  Max: 150
19
29
 
20
30
  Metrics/ModuleLength:
21
31
  Max: 200
32
+
33
+ Metrics/AbcSize:
34
+ Max: 70
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.0
1
+ 2.7.2
data/Gemfile.lock CHANGED
@@ -1,82 +1,111 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bitwise_attribute (0.2.2)
5
- activesupport (~> 5.1.5)
4
+ bitwise_attribute (0.3.4)
6
5
 
7
6
  GEM
8
7
  remote: https://rubygems.org/
9
8
  specs:
10
- activesupport (5.1.5)
9
+ activemodel (6.1.3.2)
10
+ activesupport (= 6.1.3.2)
11
+ activerecord (6.1.3.2)
12
+ activemodel (= 6.1.3.2)
13
+ activesupport (= 6.1.3.2)
14
+ activesupport (6.1.3.2)
11
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
12
- i18n (~> 0.7)
13
- minitest (~> 5.1)
14
- tzinfo (~> 1.1)
15
- ast (2.4.0)
16
- byebug (10.0.1)
17
- coderay (1.1.2)
18
- concurrent-ruby (1.0.5)
19
- diff-lcs (1.3)
20
- docile (1.1.5)
21
- i18n (0.9.5)
16
+ i18n (>= 1.6, < 2)
17
+ minitest (>= 5.1)
18
+ tzinfo (~> 2.0)
19
+ zeitwerk (~> 2.3)
20
+ ast (2.4.2)
21
+ byebug (11.1.3)
22
+ coderay (1.1.3)
23
+ concurrent-ruby (1.1.8)
24
+ diff-lcs (1.4.4)
25
+ docile (1.4.0)
26
+ ffi (1.15.1-java)
27
+ i18n (1.8.10)
22
28
  concurrent-ruby (~> 1.0)
23
- json (2.1.0)
24
- method_source (0.9.0)
25
- minitest (5.11.3)
26
- parallel (1.12.1)
27
- parser (2.5.0.5)
28
- ast (~> 2.4.0)
29
- powerpack (0.1.1)
30
- pry (0.11.3)
31
- coderay (~> 1.1.0)
32
- method_source (~> 0.9.0)
33
- pry-byebug (3.6.0)
34
- byebug (~> 10.0)
35
- pry (~> 0.10)
29
+ method_source (1.0.0)
30
+ minitest (5.14.4)
31
+ parallel (1.20.1)
32
+ parser (3.0.1.1)
33
+ ast (~> 2.4.1)
34
+ pry (0.13.1)
35
+ coderay (~> 1.1)
36
+ method_source (~> 1.0)
37
+ pry (0.13.1-java)
38
+ coderay (~> 1.1)
39
+ method_source (~> 1.0)
40
+ spoon (~> 0.0)
41
+ pry-byebug (3.9.0)
42
+ byebug (~> 11.0)
43
+ pry (~> 0.13.0)
36
44
  rainbow (3.0.0)
37
- rake (10.5.0)
38
- rspec (3.7.0)
39
- rspec-core (~> 3.7.0)
40
- rspec-expectations (~> 3.7.0)
41
- rspec-mocks (~> 3.7.0)
42
- rspec-core (3.7.1)
43
- rspec-support (~> 3.7.0)
44
- rspec-expectations (3.7.0)
45
+ rake (13.0.3)
46
+ regexp_parser (2.1.1)
47
+ rexml (3.2.5)
48
+ rspec (3.10.0)
49
+ rspec-core (~> 3.10.0)
50
+ rspec-expectations (~> 3.10.0)
51
+ rspec-mocks (~> 3.10.0)
52
+ rspec-core (3.10.1)
53
+ rspec-support (~> 3.10.0)
54
+ rspec-expectations (3.10.1)
45
55
  diff-lcs (>= 1.2.0, < 2.0)
46
- rspec-support (~> 3.7.0)
47
- rspec-mocks (3.7.0)
56
+ rspec-support (~> 3.10.0)
57
+ rspec-mocks (3.10.2)
48
58
  diff-lcs (>= 1.2.0, < 2.0)
49
- rspec-support (~> 3.7.0)
50
- rspec-support (3.7.1)
51
- rubocop (0.54.0)
59
+ rspec-support (~> 3.10.0)
60
+ rspec-support (3.10.2)
61
+ rubocop (1.15.0)
52
62
  parallel (~> 1.10)
53
- parser (>= 2.5)
54
- powerpack (~> 0.1)
63
+ parser (>= 3.0.0.0)
55
64
  rainbow (>= 2.2.2, < 4.0)
65
+ regexp_parser (>= 1.8, < 3.0)
66
+ rexml
67
+ rubocop-ast (>= 1.5.0, < 2.0)
56
68
  ruby-progressbar (~> 1.7)
57
- unicode-display_width (~> 1.0, >= 1.0.1)
58
- ruby-progressbar (1.9.0)
59
- simplecov (0.15.1)
60
- docile (~> 1.1.0)
61
- json (>= 1.8, < 3)
62
- simplecov-html (~> 0.10.0)
63
- simplecov-html (0.10.2)
64
- thread_safe (0.3.6)
65
- tzinfo (1.2.5)
66
- thread_safe (~> 0.1)
67
- unicode-display_width (1.3.0)
69
+ unicode-display_width (>= 1.4.0, < 3.0)
70
+ rubocop-ast (1.7.0)
71
+ parser (>= 3.0.1.1)
72
+ rubocop-rake (0.5.1)
73
+ rubocop
74
+ rubocop-rspec (2.3.0)
75
+ rubocop (~> 1.0)
76
+ rubocop-ast (>= 1.1.0)
77
+ ruby-progressbar (1.11.0)
78
+ simplecov (0.21.2)
79
+ docile (~> 1.1)
80
+ simplecov-html (~> 0.11)
81
+ simplecov_json_formatter (~> 0.1)
82
+ simplecov-html (0.12.3)
83
+ simplecov_json_formatter (0.1.3)
84
+ spoon (0.0.6)
85
+ ffi
86
+ sqlite3 (1.4.2)
87
+ tzinfo (2.0.4)
88
+ concurrent-ruby (~> 1.0)
89
+ unicode-display_width (2.0.0)
90
+ zeitwerk (2.4.2)
68
91
 
69
92
  PLATFORMS
70
- ruby
93
+ universal-java-11
94
+ x86_64-darwin-19
95
+ x86_64-linux
71
96
 
72
97
  DEPENDENCIES
98
+ activerecord (>= 3)
73
99
  bitwise_attribute!
74
- bundler (~> 1.16)
100
+ bundler
75
101
  pry-byebug
76
- rake (~> 10.0)
77
- rspec (~> 3.0)
78
- rubocop (~> 0.54.0)
79
- simplecov (~> 0.15.1)
102
+ rake
103
+ rspec
104
+ rubocop
105
+ rubocop-rake
106
+ rubocop-rspec
107
+ simplecov
108
+ sqlite3
80
109
 
81
110
  BUNDLED WITH
82
- 1.16.1
111
+ 2.2.16
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- [![Dependency Status](https://gemnasium.com/rikas/bitwise_attribute.svg)](https://gemnasium.com/rikas/bitwise_attribute)
2
- [![Build Status](https://travis-ci.org/rikas/bitwise_attribute.svg?branch=master)](https://travis-ci.org/rikas/bitwise_attribute)
3
-
4
1
  # BitwiseAttribute
2
+ Manipulation of bitmask attributes in your classes (typically ActiveRecord models). You can have multiple values mapped to the same column — for example when you need a User with multiple roles.
3
+
4
+ It adds a lot of helper methods so you don't have to deal with the underlying mask.
5
5
 
6
6
  ## Installation
7
7
 
@@ -24,6 +24,10 @@ Or install it yourself as:
24
24
  Include `BitwiseAttribute` and then define your attribute with `attr_bitwise`. By default it will
25
25
  use the singularized name with `_mask`.
26
26
 
27
+ Check the example below to see how to use the helpers and methods created automatically in your classes.
28
+
29
+ ## Examples
30
+
27
31
  For the `roles` attribute you need to have `role_mask` column in your model, so add the migration:
28
32
 
29
33
  ```ruby
@@ -38,18 +42,92 @@ end
38
42
  class User < ActiveRecord::Base
39
43
  include BitwiseAttribute
40
44
 
45
+ # This line will do all the magic!
46
+ #
47
+ # By default we assume that your column will be called `role_mask`.
48
+ # You can send the `column_name` option if your column has another name.
49
+ #
41
50
  attr_bitwise :roles, values: %i[user moderator admin]
42
51
  end
43
52
  ```
44
53
 
45
- You can then use
54
+ ### Instance manipulation
55
+
56
+ You can then access the `roles` field without having to know the underlying value of `role_mask`.
57
+
58
+ ```ruby
59
+ user = User.new(roles: [:user, :admin])
60
+
61
+ user.roles
62
+ #=> [:user, :admin]
63
+
64
+ user.role_mask
65
+ #=> 5
66
+
67
+ user.roles << :moderator
68
+ user.roles
69
+ #=> [:user, :admin, :moderator]
70
+ ```
71
+
72
+ You can see if a particular record has a given value:
73
+
74
+ ```ruby
75
+ user.admin?
76
+ #=> true
77
+ ```
78
+
79
+ ### Class methods
80
+
81
+ You can get all available values and correspondent mask value:
82
+
83
+ ```ruby
84
+ User.roles
85
+ #=> { :user => 1, :moderator => 2, :admin => 4 }
86
+ ```
87
+
88
+ So if you need all the keys just use:
89
+
90
+ ```ruby
91
+ User.roles.keys
92
+ #=> [:user, :moderator, :admin]
93
+ ```
94
+
95
+ ### ActiveRecord named scopes
96
+
97
+ BitwiseAttribte will add some methods for easier queries on the database:
98
+
99
+ ```ruby
100
+ User.with_roles
101
+ #=> Users that have at least one role
102
+
103
+ User.with_roles(:admin)
104
+ #=> Users that have the :admin role
105
+
106
+ User.with_roles(:admin, :moderator)
107
+ #=> Users that have the admin role AND the moderator role
108
+
109
+ User.with_any_roles(:admin, :moderator)
110
+ #=> Users that have the admin role OR the moderator role
111
+
112
+ User.with_exact_roles(:moderator)
113
+ #=> Users that have ONLY the moderator role
114
+
115
+ User.with_exact_roles(:moderator, :admin)
116
+ #=> Users that have ONLY the moderator AND admin roles
117
+
118
+ User.without_roles(:admin)
119
+ #=> Users without the admin role
120
+
121
+ User.without_roles(:admin, :moderator)
122
+ #=> Users without the admin role AND without the moderator role
123
+ ```
124
+
125
+ These are the same as using `with_roles`:
46
126
 
47
127
  ```ruby
48
- user = User.first
49
- user.roles #=> []
50
- user.roles = [:user, :admin] #=> [:user, :admin]
51
- user.save
52
- user.role_mask #=> 5
128
+ User.admin
129
+ User.user
130
+ User.admin.moderator
53
131
  ```
54
132
 
55
133
  ## Development
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
- # frozen_string_literal: true
2
-
3
1
  #!/usr/bin/env ruby
4
2
 
3
+ # frozen_string_literal: true
4
+
5
5
  require 'bundler/setup'
6
6
  require 'bitwise_attribute'
7
7
 
@@ -7,6 +7,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
7
  require 'bitwise_attribute/version'
8
8
 
9
9
  Gem::Specification.new do |spec|
10
+ spec.required_ruby_version = '>= 2.5.0'
10
11
  spec.name = 'bitwise_attribute'
11
12
  spec.version = BitwiseAttribute::VERSION
12
13
  spec.authors = ['Ricardo Otero']
@@ -24,12 +25,14 @@ Gem::Specification.new do |spec|
24
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
26
  spec.require_paths = %w[lib]
26
27
 
27
- spec.add_dependency 'activesupport', '~> 5.1.5'
28
-
29
- spec.add_development_dependency 'bundler', '~> 1.16'
28
+ spec.add_development_dependency 'activerecord', '>= 3'
29
+ spec.add_development_dependency 'bundler'
30
30
  spec.add_development_dependency 'pry-byebug'
31
- spec.add_development_dependency 'rake', '~> 10.0'
32
- spec.add_development_dependency 'rspec', '~> 3.0'
33
- spec.add_development_dependency 'rubocop', '~> 0.54.0'
34
- spec.add_development_dependency 'simplecov', '~> 0.15.1'
31
+ spec.add_development_dependency 'rake'
32
+ spec.add_development_dependency 'rspec'
33
+ spec.add_development_dependency 'rubocop'
34
+ spec.add_development_dependency 'rubocop-rake'
35
+ spec.add_development_dependency 'rubocop-rspec'
36
+ spec.add_development_dependency 'simplecov'
37
+ spec.add_development_dependency 'sqlite3'
35
38
  end
@@ -3,52 +3,39 @@
3
3
  require 'active_support'
4
4
  require 'active_support/concern'
5
5
  require 'active_support/core_ext'
6
+
6
7
  require 'bitwise_attribute/version'
7
8
  require 'bitwise_attribute/values_list'
9
+ require 'bitwise_attribute/active_record_methods'
8
10
 
9
11
  module BitwiseAttribute
10
- extend ActiveSupport::Concern
12
+ def self.included(base)
13
+ base.extend ClassMethods
14
+ end
11
15
 
12
- class_methods do
13
- def attr_bitwise(name, column_name: nil, values:)
14
- column_name ||= "#{name.to_s.singularize}_mask"
16
+ module ClassMethods
17
+ include BitwiseAttribute::ActiveRecordMethods
15
18
 
16
- # Check if the values is an array or hash with valid values. Raise ArgumentError otherwise.
17
- validate_values!(values)
19
+ def attr_bitwise(name, values:, column_name: nil)
20
+ column_name ||= "#{name.to_s.singularize}_mask"
18
21
 
19
22
  mapping = build_mapping(values)
20
23
 
21
- @mapping ||= {}
22
- @mapping[name] = mapping
23
-
24
24
  define_class_methods(name, column_name, mapping)
25
- define_instante_methods(name, column_name, mapping)
25
+ define_instance_methods(name, column_name, mapping)
26
26
  end
27
27
 
28
+ private
29
+
28
30
  def define_class_methods(name, column_name, mapping)
29
- # Class methods
30
31
  define_singleton_method(name) do
31
32
  mapping
32
33
  end
33
34
 
34
- define_singleton_method("with_#{name}") do |*keys|
35
- where(column_name => bitwise_union(keys, name))
36
- end
37
-
38
- define_singleton_method("with_all_#{name}") do |*keys|
39
- where(column_name => bitwise_intersection(keys, name))
40
- end
41
-
42
- # Defines a class method for each key of the mapping, returning records that have *at least*
43
- # the corresponding value.
44
- mapping.keys.each do |key|
45
- define_singleton_method(key) do
46
- send("with_#{key}")
47
- end
48
- end
35
+ define_named_scopes(name, column_name, mapping) if defined?(ActiveRecord)
49
36
  end
50
37
 
51
- def define_instante_methods(name, column_name, mapping)
38
+ def define_instance_methods(name, column_name, mapping)
52
39
  define_method(name) do
53
40
  roles = value_getter(column_name, mapping)
54
41
 
@@ -61,7 +48,7 @@ module BitwiseAttribute
61
48
  end
62
49
 
63
50
  # Adds a boolean method for each key (ex: admin?)
64
- mapping.keys.each do |key|
51
+ mapping.each_key do |key|
65
52
  define_method("#{key}?") do
66
53
  value?(column_name, mapping[key])
67
54
  end
@@ -72,64 +59,8 @@ module BitwiseAttribute
72
59
  # Each sym get a power of 2 value
73
60
  def build_mapping(values)
74
61
  {}.tap do |hash|
75
- if values.is_a?(Hash)
76
- hash.merge!(values.sort_by { |_, value| value }.to_h)
77
- else
78
- values.each_with_index { |key, index| hash[key] = 2**index }
79
- end
80
- end
81
- end
82
-
83
- # Validates the numeric values for each key. If it's not a power of 2 then raise ArgumentError.
84
- def validate_values!(values)
85
- return true if values.is_a?(Array)
86
-
87
- values.reject { |_, value| (Math.log2(value) % 1.0).zero? }.tap do |invalid_options|
88
- if invalid_options.any?
89
- raise(ArgumentError, "Values should be a power of 2 (#{invalid_options})")
90
- end
91
- end
92
- end
93
-
94
- def mapping_for_name(name)
95
- @mapping[name.to_sym]
96
- end
97
-
98
- def values_for_column(name)
99
- mapping_for_name(name).values
100
- end
101
-
102
- def map_to_values(name, keys)
103
- mapping = mapping_for_name(name)
104
-
105
- keys.map { |key| mapping[key.to_sym] }.compact
106
- end
107
-
108
- def bitwise_union(keys, name)
109
- mask = []
110
-
111
- mapped = map_to_values(name, keys)
112
-
113
- mapped.each do |mv|
114
- values_for_column(name).each do |value|
115
- mask << (mv | value)
116
- end
62
+ values.each_with_index { |key, index| hash[key] = (0b1 << index) }
117
63
  end
118
-
119
- mask.uniq
120
- end
121
-
122
- def bitwise_intersection(keys, name)
123
- mask = []
124
-
125
- mapped = map_to_values(name, keys)
126
- mapped = mapped.reduce(&:|)
127
-
128
- values_for_column(name).each do |value|
129
- mask << (value | mapped)
130
- end
131
-
132
- mask.uniq
133
64
  end
134
65
  end
135
66
 
@@ -147,19 +78,15 @@ module BitwiseAttribute
147
78
  def value_setter(mask_column, values, mapping)
148
79
  send("#{mask_column}=", 0)
149
80
 
150
- values.each do |value|
151
- raise(ArgumentError, "Unknown value #{value}!") unless mapping[value]
81
+ values = values.map(&:to_sym).compact.uniq
152
82
 
153
- add_value(mask_column, mapping[value])
154
- end
83
+ values &= mapping.keys
84
+
85
+ values.each { |value| send("#{mask_column}=", send(mask_column) | mapping[value]) }
155
86
  end
156
87
 
157
- # Return if value presents in mask (raw value)
88
+ # Return if value is present in mask (raw value)
158
89
  def value?(mask_column, val)
159
90
  send(mask_column) & val != 0
160
91
  end
161
-
162
- def add_value(mask_column, val)
163
- send("#{mask_column}=", send(mask_column) | val)
164
- end
165
92
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BitwiseAttribute
4
+ module ActiveRecordMethods
5
+ def define_named_scopes(name, column_name, mapping)
6
+ define_singleton_method("with_#{name}") do |*keys|
7
+ keys = cleanup_keys(keys, mapping)
8
+
9
+ return [] unless keys&.any?
10
+
11
+ records = where("#{column_name} & #{mapping[keys.first]} = #{mapping[keys.first]}")
12
+
13
+ keys[1..-1].each do |key|
14
+ records = records.where("#{column_name} & #{mapping[key]} = #{mapping[key]}")
15
+ end
16
+
17
+ records
18
+ end
19
+
20
+ define_singleton_method("with_any_#{name}") do |*keys|
21
+ keys = cleanup_keys(keys, mapping)
22
+
23
+ return where.not(column_name => nil) unless keys&.any?
24
+
25
+ records = where("#{column_name} & #{mapping[keys.first]} = #{mapping[keys.first]}")
26
+
27
+ keys[1..-1].each do |key|
28
+ records = records.or(where("#{column_name} & #{mapping[key]} = #{mapping[key]}"))
29
+ end
30
+
31
+ records
32
+ end
33
+
34
+ define_singleton_method("with_exact_#{name}") do |*keys|
35
+ keys = cleanup_keys(keys, mapping)
36
+
37
+ return [] unless keys&.any?
38
+
39
+ records = send("with_#{name}", keys)
40
+
41
+ (mapping.keys - keys).each do |key|
42
+ records = records.where("#{column_name} & #{mapping[key]} != #{mapping[key]}")
43
+ end
44
+
45
+ records
46
+ end
47
+
48
+ define_singleton_method("without_#{name}") do |*keys|
49
+ keys = cleanup_keys(keys, mapping)
50
+
51
+ return where(column_name => nil).or(where(column_name => 0)) unless keys&.any?
52
+
53
+ records = where("#{column_name} & #{mapping[keys.first]} != #{mapping[keys.first]}")
54
+
55
+ keys[1..-1].each do |key|
56
+ records = records.where("#{column_name} & #{mapping[key]} != #{mapping[key]}")
57
+ end
58
+
59
+ records
60
+ end
61
+
62
+ # Defines a class method for each key of the mapping, returning records that have *at least*
63
+ # the corresponding value.
64
+ mapping.each_key do |key|
65
+ define_singleton_method(key) do
66
+ send("with_#{name}", key)
67
+ end
68
+ end
69
+ end
70
+
71
+ def cleanup_keys(keys, mapping)
72
+ return [] unless keys
73
+
74
+ clean = keys.flatten.map(&:to_sym).compact.uniq
75
+
76
+ clean & mapping.keys # only roles that we know about
77
+ end
78
+ end
79
+ end
@@ -3,10 +3,10 @@
3
3
  module BitwiseAttribute
4
4
  class ValuesList < Array
5
5
  def initialize(field, record, values)
6
+ super(concat(values))
7
+
6
8
  @field = field
7
9
  @record = record
8
-
9
- concat(values)
10
10
  end
11
11
 
12
12
  def <<(value)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BitwiseAttribute
4
- VERSION = '0.2.2'
4
+ VERSION = '0.3.4'
5
5
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitwise_attribute
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ricardo Otero
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-28 00:00:00.000000000 Z
11
+ date: 2021-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.1.5
20
- type: :runtime
19
+ version: '3'
20
+ type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 5.1.5
26
+ version: '3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.16'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.16'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pry-byebug
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -56,58 +56,100 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '10.0'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '10.0'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '3.0'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '3.0'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: 0.54.0
103
+ version: '0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - "~>"
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: 0.54.0
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: simplecov
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
- - - "~>"
129
+ - - ">="
102
130
  - !ruby/object:Gem::Version
103
- version: 0.15.1
131
+ version: '0'
104
132
  type: :development
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
- - - "~>"
136
+ - - ">="
109
137
  - !ruby/object:Gem::Version
110
- version: 0.15.1
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
111
153
  description: Bitwise attribute for ruby class and Rails model.
112
154
  email:
113
155
  - oterosantos@gmail.com
@@ -115,11 +157,11 @@ executables: []
115
157
  extensions: []
116
158
  extra_rdoc_files: []
117
159
  files:
160
+ - ".github/workflows/ci.yml"
118
161
  - ".gitignore"
119
162
  - ".rspec"
120
163
  - ".rubocop.yml"
121
164
  - ".ruby-version"
122
- - ".travis.yml"
123
165
  - Gemfile
124
166
  - Gemfile.lock
125
167
  - LICENSE.txt
@@ -129,13 +171,14 @@ files:
129
171
  - bin/setup
130
172
  - bitwise_attribute.gemspec
131
173
  - lib/bitwise_attribute.rb
174
+ - lib/bitwise_attribute/active_record_methods.rb
132
175
  - lib/bitwise_attribute/values_list.rb
133
176
  - lib/bitwise_attribute/version.rb
134
177
  homepage: https://github.com/rikas/bitwise_attribute
135
178
  licenses:
136
179
  - MIT
137
180
  metadata: {}
138
- post_install_message:
181
+ post_install_message:
139
182
  rdoc_options: []
140
183
  require_paths:
141
184
  - lib
@@ -143,16 +186,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
186
  requirements:
144
187
  - - ">="
145
188
  - !ruby/object:Gem::Version
146
- version: '0'
189
+ version: 2.5.0
147
190
  required_rubygems_version: !ruby/object:Gem::Requirement
148
191
  requirements:
149
192
  - - ">="
150
193
  - !ruby/object:Gem::Version
151
194
  version: '0'
152
195
  requirements: []
153
- rubyforge_project:
154
- rubygems_version: 2.7.3
155
- signing_key:
196
+ rubygems_version: 3.1.4
197
+ signing_key:
156
198
  specification_version: 4
157
199
  summary: Bitwise attribute for ruby class and Rails model.
158
200
  test_files: []
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.5.0
5
- before_install: gem install bundler -v 1.16.1