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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc824cf59452e64b1e34422e7416920dd725ea7d
4
- data.tar.gz: 78a184dd4eda1d311ef1246f089babc00711a22b
3
+ metadata.gz: cf9f6971a5470e30369fcfa61814a7533ac62b89
4
+ data.tar.gz: 559897cbd82a915ae89b0a462da4e40d8f8d9a3a
5
5
  SHA512:
6
- metadata.gz: 1e3d053623af2a5c60eb9d1818849d72b9e1d66801d2c9bb07fa12a63462770614f3a87e7b802470ca5cfd7609a0aab167d5fa2b3032c2477bdc7c48c86653ae
7
- data.tar.gz: c45ced97d18462bf25ddfa2b4221b26e69ea1b75f293c6b200c457a415697c144f14d0c00e72dd781a24214f5e3b7e16236397103a8329a482a6a75eb4219726
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 `nil` for `_was` and `false` for `_changed?` since the previous changes have been persisted.
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/>
@@ -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| super(value); set_bitfield_value(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)
@@ -1,3 +1,3 @@
1
1
  module Bitfields
2
- Version = VERSION = "0.11.0"
2
+ Version = VERSION = "0.12.0"
3
3
  end
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.11.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-09-04 00:00:00.000000000 Z
11
+ date: 2019-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord