bitfields 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +47 -13
- data/lib/bitfields.rb +35 -3
- data/lib/bitfields/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf9f6971a5470e30369fcfa61814a7533ac62b89
|
4
|
+
data.tar.gz: 559897cbd82a915ae89b0a462da4e40d8f8d9a3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd96cded51293734f1dc013966f26a42d90710efb082f628076728e96425a31011c6cfd8a964d9cb0aa7bdc7f63d2669e6655eb96a37423fddf978aaa35027fc
|
7
|
+
data.tar.gz: b68f9ec05b94f11ead65c5690a19f72199dc50b0d3434e82d3a202c9c22a9a5f7793a195310c28123b334f87c4fc6213643ac1fb196dd188e61d114ee03d695d
|
data/Readme.md
CHANGED
@@ -17,7 +17,7 @@ user.my_bits # => 3
|
|
17
17
|
- Individual added methods (i.e, `seller_was`, `seller_changed?`, etc..) can be deactivated with `bitfield ..., added_instance_methods: false`
|
18
18
|
- **Note**: ActiveRecord 5.2 changes the behavior of `_was` and `_changed?` methods when used in the context of an `after_save` callback.
|
19
19
|
- ActiveRecord 5.1 will use the use the values that were _just_ changed.
|
20
|
-
- ActiveRecord 5.2, however, will return
|
20
|
+
- ActiveRecord 5.2, however, will return the current value for `_was` and `false` for `_changed?` since the previous changes have been persisted.
|
21
21
|
- adds scopes `User.seller.sensible.first` (deactivate with `bitfield ..., scopes: false`)
|
22
22
|
- builds sql `User.bitfield_sql(insane: true, sensible: false) # => '(users.my_bits & 6) = 1'`
|
23
23
|
- builds sql with OR condition `User.bitfield_sql({ insane: true, sensible: true }, query_mode: :bit_operator_or) # => '(users.my_bits & 2) = 2 OR (users.bits & 4) = 4'`
|
@@ -25,18 +25,6 @@ user.my_bits # => 3
|
|
25
25
|
- builds update sql `User.set_bitfield_sql(insane: true, sensible: false) == 'my_bits = (my_bits | 6) - 4'`
|
26
26
|
- **faster sql than any other bitfield lib** through combination of multiple bits into a single sql statement
|
27
27
|
- gives access to bits `User.bitfields[:my_bits][:sensible] # => 4`
|
28
|
-
- [`ActiveRecord::AttributeMethods::Dirty`](https://api.rubyonrails.org/v5.1.7/classes/ActiveRecord/AttributeMethods/Dirty.html) and [`ActiveModel::Dirty`](https://api.rubyonrails.org/v5.1.7/classes/ActiveModel/Dirty.html) methods can be used on each bitfield:
|
29
|
-
```ruby
|
30
|
-
user = User.new(seller: false)
|
31
|
-
user.seller = true
|
32
|
-
user.will_save_change_to_seller? # => true
|
33
|
-
user.seller_change_to_be_saved # => [false, true]
|
34
|
-
|
35
|
-
user.save
|
36
|
-
|
37
|
-
user.seller_before_last_save # => false
|
38
|
-
user.saved_change_to_seller # => [false, true]
|
39
|
-
```
|
40
28
|
|
41
29
|
Install
|
42
30
|
=======
|
@@ -54,6 +42,49 @@ t.integer :my_bits, default: 0, null: false
|
|
54
42
|
add_column :users, :my_bits, :integer, default: 0, null: false
|
55
43
|
```
|
56
44
|
|
45
|
+
Instance Methods
|
46
|
+
================
|
47
|
+
|
48
|
+
### Global Bitfield Methods
|
49
|
+
| Method Name | Example (`user = User.new(seller: true, insane: true`) | Result |
|
50
|
+
|--------------------|---------------------------------------------------------|-------------------------------------------------------------|
|
51
|
+
| `bitfield_values` | `user.bitfield_values` | `{"seller" => true, "insane" => true, "sensible" => false}` |
|
52
|
+
| `bitfield_changes` | `user.bitfield_changes` | `{"seller" => [false, true], "insane" => [false, true]}` |
|
53
|
+
|
54
|
+
### Individual Bit Methods
|
55
|
+
#### Model Getters / Setters
|
56
|
+
| Method Name | Example (`user = User.new`) | Result |
|
57
|
+
|----------------|-----------------------------|---------|
|
58
|
+
| `#{bit_name}` | `user.seller` | `false` |
|
59
|
+
| `#{bit_name}=` | `user.seller = true` | `true` |
|
60
|
+
| `#{bit_name}?` | `user.seller?` | `true` |
|
61
|
+
|
62
|
+
#### Dirty Methods:
|
63
|
+
|
64
|
+
Some, not all, [`ActiveRecord::AttributeMethods::Dirty`](https://api.rubyonrails.org/v5.1.7/classes/ActiveRecord/AttributeMethods/Dirty.html) and [`ActiveModel::Dirty`](https://api.rubyonrails.org/v5.1.7/classes/ActiveModel/Dirty.html) methods can be used on each bitfield:
|
65
|
+
|
66
|
+
##### Before Model Persistence
|
67
|
+
| Method Name | Example (`user = User.new`) | Result |
|
68
|
+
|------------------------------------|------------------------------------|-----------------|
|
69
|
+
| `#{bit_name}_was` | `user.seller_was` | `false` |
|
70
|
+
| `#{bit_name}_in_database` | `user.seller_in_database` | `false` |
|
71
|
+
| `#{bit_name}_change` | `user.seller_change` | `[false, true]` |
|
72
|
+
| `#{bit_name}_change_to_be_saved` | `user.seller_change_to_be_saved` | `[false, true]` |
|
73
|
+
| `#{bit_name}_changed?` | `user.seller_changed?` | `true` |
|
74
|
+
| `will_save_change_to_#{bit_name}?` | `user.will_save_change_to_seller?` | `true` |
|
75
|
+
| `#{bit_name}_became_true?` | `user.seller_became_true?` | `true` |
|
76
|
+
| `#{bit_name}_became_false?` | `user.seller_became_false?` | `false` |
|
77
|
+
|
78
|
+
|
79
|
+
##### After Model Persistence
|
80
|
+
| Method Name | Example (`user = User.create(seller: true)`) | Result |
|
81
|
+
|--------------------------------|---------------------------------------------------|-----------------|
|
82
|
+
| `#{bit_name}_before_last_save` | `user.seller_before_last_save` | `false` |
|
83
|
+
| `saved_change_to_#{bit_name}` | `user.saved_change_to_seller` | `[false, true]` |
|
84
|
+
| `saved_change_to_#{bit_name}?` | `user.saved_change_to_seller?` | `true` |
|
85
|
+
|
86
|
+
- **Note**: These methods are dynamically defined for each bitfield, and function separately from the real `ActiveRecord::AttributeMethods::Dirty`/`ActiveModel::Dirty` methods. As such, generic methods (e.g. `attribute_before_last_save(:attribute)`) will not work.
|
87
|
+
|
57
88
|
Examples
|
58
89
|
========
|
59
90
|
Update all users
|
@@ -120,6 +151,9 @@ Authors
|
|
120
151
|
- [szTheory](https://github.com/szTheory)
|
121
152
|
- [Reed G. Law](https://github.com/reedlaw)
|
122
153
|
- [Rael Gugelmin Cunha](https://github.com/reedlaw)
|
154
|
+
- [Alan Wong](https://github.com/naganowl)
|
155
|
+
- [Andrew Bates](https://github.com/a-bates)
|
156
|
+
- [Shirish Pampoorickal](https://github.com/shirish-pampoorickal)
|
123
157
|
|
124
158
|
[Michael Grosser](http://grosser.it)<br/>
|
125
159
|
michael@grosser.it<br/>
|
data/lib/bitfields.rb
CHANGED
@@ -82,11 +82,19 @@ module Bitfields
|
|
82
82
|
def add_bitfield_methods(column, options)
|
83
83
|
bitfields[column].keys.each do |bit_name|
|
84
84
|
if options[:added_instance_methods] != false
|
85
|
-
attribute bit_name, :boolean, default: false
|
86
|
-
|
87
85
|
define_method(bit_name) { bitfield_value(bit_name) }
|
88
86
|
define_method("#{bit_name}?") { bitfield_value(bit_name) }
|
89
|
-
define_method("#{bit_name}=") { |value|
|
87
|
+
define_method("#{bit_name}=") { |value| set_bitfield_value(bit_name, value) }
|
88
|
+
|
89
|
+
# Dirty methods usable in before_save contexts
|
90
|
+
define_method("#{bit_name}_was") { bitfield_value_was(bit_name) }
|
91
|
+
alias_method "#{bit_name}_in_database", "#{bit_name}_was"
|
92
|
+
|
93
|
+
define_method("#{bit_name}_change") { bitfield_value_change(bit_name) }
|
94
|
+
alias_method "#{bit_name}_change_to_be_saved", "#{bit_name}_change"
|
95
|
+
|
96
|
+
define_method("#{bit_name}_changed?") { bitfield_value_change(bit_name).present? }
|
97
|
+
alias_method "will_save_change_to_#{bit_name}?", "#{bit_name}_changed?"
|
90
98
|
|
91
99
|
define_method("#{bit_name}_became_true?") do
|
92
100
|
value = bitfield_value(bit_name)
|
@@ -96,6 +104,11 @@ module Bitfields
|
|
96
104
|
value = bitfield_value(bit_name)
|
97
105
|
!value && send("#{bit_name}_was") != value
|
98
106
|
end
|
107
|
+
|
108
|
+
# Dirty methods usable in after_save contexts
|
109
|
+
define_method("#{bit_name}_before_last_save") { bitfield_value_before_last_save(bit_name) }
|
110
|
+
define_method("saved_change_to_#{bit_name}") { saved_change_to_bitfield_value(bit_name) }
|
111
|
+
define_method("saved_change_to_#{bit_name}?") { saved_change_to_bitfield_value(bit_name).present? }
|
99
112
|
end
|
100
113
|
|
101
114
|
if options[:scopes] != false
|
@@ -186,6 +199,25 @@ module Bitfields
|
|
186
199
|
send("#{column}_was") & bit != 0
|
187
200
|
end
|
188
201
|
|
202
|
+
def bitfield_value_before_last_save(bit_name)
|
203
|
+
column, bit, _ = bitfield_info(bit_name)
|
204
|
+
column_before_last_save = send("#{column}_before_last_save")
|
205
|
+
column_before_last_save.nil? ? nil : column_before_last_save & bit != 0
|
206
|
+
end
|
207
|
+
|
208
|
+
def bitfield_value_change(bit_name)
|
209
|
+
values = [bitfield_value_was(bit_name), bitfield_value(bit_name)]
|
210
|
+
values unless values[0] == values[1]
|
211
|
+
end
|
212
|
+
|
213
|
+
def saved_change_to_bitfield_value(bit_name)
|
214
|
+
value_before_last_save = bitfield_value_before_last_save(bit_name)
|
215
|
+
current_value = bitfield_value(bit_name)
|
216
|
+
unless value_before_last_save.nil? || (value_before_last_save == current_value)
|
217
|
+
[value_before_last_save, current_value]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
189
221
|
def set_bitfield_value(bit_name, value)
|
190
222
|
column, bit, current_value = bitfield_info(bit_name)
|
191
223
|
new_value = TRUE_VALUES.include?(value)
|
data/lib/bitfields/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitfields
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|