active_flag 1.5.0 → 1.6.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: f156db5cdf6e7c81eeec5d35fe84a5bf52d3543e1a274eb120ebe5961c3a2aae
4
- data.tar.gz: 800c0c276ea269197360587b2b091fbb4208bf1312949eba7fb41568bea6b684
3
+ metadata.gz: 2410c1b0af6f52df6e74bbbb1dee7f4aa445d7914ec9f63caffc843a4f8453a0
4
+ data.tar.gz: b4877beab21724bf362fe26fdeb3e3d7d9de532170a46acf638dcad36df15d09
5
5
  SHA512:
6
- metadata.gz: e0756d76fa4f609f39858f482a3f60cc429446fa8e3781ae157554e9cb5a6eb788663d3a46a32eaf360750083f5b771fdcffdbe4bb96c8166026e1f2e03bf03f
7
- data.tar.gz: 4a1a0a5e0ba214b08977d04aa8b1f9ab41ee2a8906f968d05da05da1e35066e7208853405493073ff61cdbcd0972abedd2f3440f4837a0ff6f398b7a0c26ab0e
6
+ metadata.gz: 84efcd90ecdc82c0e93074902a8bee8f88fb114035a1680808b1f53840e8224388d372872aa3d3d392ad4c36bd0bc5301d48eba21adb5a275b869c5b90d3098f
7
+ data.tar.gz: 721d7dec4c58f396427bb50dfa4c577bf9aa23bfb871c27f4da8b1d20a9d1aa026e2ec163bdf58927548a4c28ff8f389008fb639d58f8b23f3d3c38c7fb68004
data/.travis.yml CHANGED
@@ -1,8 +1,11 @@
1
- sudo: false
2
1
  language: ruby
3
2
  rvm:
4
- - 2.5.3
5
- before_install: gem install bundler -v 1.13.6
3
+ - 2.5
4
+ - 2.6
5
+ - 2.7
6
+ before_install: gem install bundler -v 1.16.2
6
7
  gemfile:
8
+ - gemfiles/5.0.gemfile
9
+ - gemfiles/5.1.gemfile
7
10
  - gemfiles/5.2.gemfile
8
11
  - gemfiles/6.0.gemfile
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Kenn Ejima
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -39,9 +39,13 @@ profile.languages = [:spanish, :japanese] # Direct assignment that works with
39
39
  Profile.languages.maps #=> {:english=>1, :spanish=>2, :chinese=>4, :french=>8, :japanese=>16 }
40
40
  Profile.languages.humans #=> {:english=>"English", :spanish=>"Spanish", :chinese=>"Chinese", :french=>"French", :japanese=>"Japanese"}
41
41
  Profile.languages.pairs #=> {"English"=>:english, "Spanish"=>:spanish, "Chinese"=>:chinese, "French"=>:french, "Japanese"=>:japanese}
42
+ Profile.languages.to_array(3) #=> [:english, :spanish]
42
43
 
43
44
  # Scope methods
44
45
  Profile.where_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 > 0
46
+ Profile.where_all_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 = 10
47
+ Profile.where_not_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 = 0
48
+ Profile.where_not_all_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 < 10
45
49
  Profile.languages.set_all!(:chinese) #=> UPDATE "profiles" SET languages = COALESCE(languages, 0) | 4
46
50
  Profile.languages.unset_all!(:chinese) #=> UPDATE "profiles" SET languages = COALESCE(languages, 0) & ~4
47
51
  ```
@@ -54,7 +58,7 @@ gem 'active_flag'
54
58
 
55
59
  ### Migration
56
60
 
57
- Always set `0` as a default.
61
+ It is recommended to set `0` by default.
58
62
 
59
63
  ```ruby
60
64
  t.integer :languages, null: false, default: 0, limit: 8
@@ -66,7 +70,8 @@ add_column :users, :languages, :integer, null: false, default: 0, limit: 8
66
70
 
67
71
  ## Query
68
72
 
69
- For a querying purpose, use `where_[column]` scope.
73
+ For a querying purpose, use `where_[column]`, `where_all_[column]`,
74
+ `where_not_[column]` and `where_not_all_[column]` scopes.
70
75
 
71
76
  ```ruby
72
77
  Profile.where_languages(:french) #=> SELECT * FROM profiles WHERE languages & 8 > 0
@@ -78,12 +83,24 @@ Also takes multiple values.
78
83
  Profile.where_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 > 0
79
84
  ```
80
85
 
81
- By default, it searches with `or` operation, so the query above returns profiles that have either French or Spanish.
86
+ By default, it returns profiles that have either French or Spanish.
82
87
 
83
- If you want to change it to `and` operation, you can specify:
88
+ To get profiles that have both French and Spanish, use:
84
89
 
85
90
  ```ruby
86
- Profile.where_languages(:french, :spanish, op: :and) #=> SELECT * FROM profiles WHERE languages = 10
91
+ Profile.where_all_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 = 10
92
+ ```
93
+
94
+ To get profiles that do not have either French or Spanish, use:
95
+
96
+ ```ruby
97
+ Profile.where_not_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 = 0
98
+ ```
99
+
100
+ To get profiles that do not have both French and Spanish, use:
101
+
102
+ ```ruby
103
+ Profile.where_not_all_languages(:french, :spanish) #=> SELECT * FROM profiles WHERE languages & 10 < 10
87
104
  ```
88
105
 
89
106
  ## Translation
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "activerecord", "~> 5.0"
4
+
5
+ group :development, :test do
6
+ gem "bundler"
7
+ gem "rake"
8
+ gem "minitest"
9
+ gem "sqlite3"
10
+ end
11
+
12
+ gemspec :path => "../"
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "activerecord", "~> 5.1"
4
+
5
+ group :development, :test do
6
+ gem "bundler"
7
+ gem "rake"
8
+ gem "minitest"
9
+ gem "sqlite3"
10
+ end
11
+
12
+ gemspec :path => "../"
@@ -5,14 +5,14 @@ module ActiveFlag
5
5
  def initialize(column, keys, klass)
6
6
  @column = column
7
7
  @keys = keys.freeze
8
- @maps = Hash[keys.map.with_index{|key, i| [key, 2**i] }].freeze
8
+ @maps = Hash[keys.map.with_index{ |key, i| [key, 2**i] }].freeze
9
9
  @klass = klass
10
10
  end
11
11
 
12
12
  def humans
13
13
  @humans ||= {}
14
14
  @humans[I18n.locale] ||= begin
15
- @keys.map{|key| [key, human(key)] }.to_h
15
+ @keys.map { |key| [key, human(key)] }.to_h
16
16
  end
17
17
  end
18
18
 
@@ -34,7 +34,8 @@ module ActiveFlag
34
34
 
35
35
  def to_i(arg)
36
36
  arg = [arg] unless arg.is_a?(Enumerable)
37
- arg.map{|s| s && @maps[s.to_s.to_sym] || 0 }.sum
37
+ arg = arg.uniq
38
+ arg.map { |s| s && @maps[s.to_s.to_sym] || 0 }.sum
38
39
  end
39
40
 
40
41
  def to_value(instance, integer)
@@ -42,7 +43,7 @@ module ActiveFlag
42
43
  end
43
44
 
44
45
  def to_array(integer)
45
- @maps.map{|key, mask| (integer & mask > 0) ? key : nil }.compact
46
+ @maps.map { |key, mask| (integer & mask > 0) ? key : nil }.compact
46
47
  end
47
48
 
48
49
  private
@@ -58,7 +59,7 @@ module ActiveFlag
58
59
  defaults << :"active_flag.#{@column}.#{key}"
59
60
  defaults << options.delete(:default) if options[:default]
60
61
  defaults << key.to_s.humanize
61
- I18n.translate defaults.shift, options.reverse_merge(count: 1, default: defaults)
62
+ I18n.translate defaults.shift, **options.reverse_merge(count: 1, default: defaults)
62
63
  end
63
64
  end
64
65
  end
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  module ActiveFlag
2
4
  class Value < Set
3
5
  def with(instance, definition)
@@ -8,7 +10,7 @@ module ActiveFlag
8
10
  end
9
11
 
10
12
  def raw
11
- @instance.read_attribute(@column)
13
+ @instance.read_attribute(@column).to_i
12
14
  end
13
15
 
14
16
  def to_human
@@ -29,12 +31,12 @@ module ActiveFlag
29
31
 
30
32
  def set!(key, options={})
31
33
  set(key)
32
- @instance.save!(options)
34
+ @instance.save!(**options)
33
35
  end
34
36
 
35
37
  def unset!(key, options={})
36
38
  unset(key)
37
- @instance.save!(options)
39
+ @instance.save!(**options)
38
40
  end
39
41
 
40
42
  def set?(key)
@@ -1,3 +1,3 @@
1
1
  module ActiveFlag
2
- VERSION = '1.5.0'
2
+ VERSION = '1.6.0'
3
3
  end
data/lib/active_flag.rb CHANGED
@@ -20,7 +20,7 @@ module ActiveFlag
20
20
 
21
21
  # Getter
22
22
  define_method column do
23
- self.class.active_flags[column].to_value(self, read_attribute(column))
23
+ self.class.active_flags[column].to_value(self, read_attribute(column).to_i)
24
24
  end
25
25
 
26
26
  # Setter
@@ -35,15 +35,37 @@ module ActiveFlag
35
35
 
36
36
  # Scopes
37
37
  define_singleton_method "where_#{column}" do |*args|
38
- options = args.extract_options!
39
- integer = active_flags[column].to_i(args)
40
- column_name = connection.quote_table_name_for_assignment(table_name, column)
38
+ options, integer, column_name = send "_where_#{column}", *args
41
39
  if options[:op] == :and
40
+ ActiveSupport::Deprecation.warn('op: :and is deprecated, use where_all instead')
42
41
  where("#{column_name} & #{integer} = #{integer}")
43
42
  else
44
43
  where("#{column_name} & #{integer} > 0")
45
44
  end
46
45
  end
46
+
47
+ define_singleton_method "where_all_#{column}" do |*args|
48
+ _options, integer, column_name = send "_where_#{column}", *args
49
+ where("#{column_name} & #{integer} = #{integer}")
50
+ end
51
+
52
+ define_singleton_method "where_not_#{column}" do |*args|
53
+ _options, integer, column_name = send "_where_#{column}", *args
54
+ where("#{column_name} & #{integer} = 0")
55
+ end
56
+
57
+ define_singleton_method "where_not_all_#{column}" do |*args|
58
+ _options, integer, column_name = send "_where_#{column}", *args
59
+ where("#{column_name} & #{integer} < #{integer}")
60
+ end
61
+
62
+ define_singleton_method "_where_#{column}" do |*args|
63
+ return [
64
+ args.extract_options!,
65
+ active_flags[column].to_i(args),
66
+ connection.quote_table_name_for_assignment(table_name, column)
67
+ ]
68
+ end
47
69
  end
48
70
  end
49
71
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_flag
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenn Ejima
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-11 00:00:00.000000000 Z
11
+ date: 2022-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -90,11 +90,14 @@ files:
90
90
  - ".gitignore"
91
91
  - ".travis.yml"
92
92
  - Gemfile
93
+ - LICENSE
93
94
  - README.md
94
95
  - Rakefile
95
96
  - active_flag.gemspec
96
97
  - bin/console
97
98
  - bin/setup
99
+ - gemfiles/5.0.gemfile
100
+ - gemfiles/5.1.gemfile
98
101
  - gemfiles/5.2.gemfile
99
102
  - gemfiles/6.0.gemfile
100
103
  - lib/active_flag.rb
@@ -105,7 +108,7 @@ files:
105
108
  homepage: https://github.com/kenn/active_flag
106
109
  licenses: []
107
110
  metadata: {}
108
- post_install_message:
111
+ post_install_message:
109
112
  rdoc_options: []
110
113
  require_paths:
111
114
  - lib
@@ -120,8 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
123
  - !ruby/object:Gem::Version
121
124
  version: '0'
122
125
  requirements: []
123
- rubygems_version: 3.0.1
124
- signing_key:
126
+ rubygems_version: 3.0.9
127
+ signing_key:
125
128
  specification_version: 4
126
129
  summary: Bit array for ActiveRecord
127
130
  test_files: []