rearmed 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -1
- data/README.md +111 -98
- data/Rakefile +20 -0
- data/lib/generators/rearmed/setup_generator.rb +1 -55
- data/lib/rearmed.rb +6 -155
- data/lib/rearmed/default_enabled_patches.hash +57 -0
- data/lib/rearmed/exceptions.rb +23 -0
- data/lib/rearmed/methods.rb +109 -0
- data/lib/rearmed/monkey_patches/array.rb +1 -1
- data/lib/rearmed/monkey_patches/hash.rb +19 -3
- data/lib/rearmed/monkey_patches/rails.rb +22 -5
- data/lib/rearmed/monkey_patches/rails_4.rb +1 -1
- data/lib/rearmed/version.rb +1 -1
- data/test/tc_rearmed.rb +16 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1c1c9a931a133791cfbdacdbfd5ccb01f50234d
|
4
|
+
data.tar.gz: 6daedcedcc902bfed66cad975fbcf99f34724163
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00253c513c5b1e4ba17485a1c7e72a2c5070e3e80121d8a612f5c8ebe10f06d04bff262bd117856a9fcffa0f1254e9fc9de5b50074bc61b126333e8a9be42624
|
7
|
+
data.tar.gz: c52b3d027600904d10d8ba89b3d9cb587ab6688c2b0c19a72fdb8b3d4766d177fc0d26d061283240ff86c277a515011bbb8c45c14a1409534492fb18d8aee341
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
---------
|
3
3
|
|
4
|
-
-
|
4
|
+
- **1.2.1 - Jan 24, 2017**
|
5
|
+
- Add Hash `join`, `to_struct`
|
6
|
+
- Fix `find_duplicates`
|
7
|
+
- Some minor refractoring
|
5
8
|
- **1.2.0 - September 3, 2016**
|
6
9
|
- Add Minitest patches `assert_changed` & `assert_not_changed`
|
7
10
|
- Remove `dedupe` in favor of new `find_duplicates`
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Rearmed Ruby
|
2
2
|
<a href='https://ko-fi.com/A5071NK' target='_blank'><img height='32' style='border:0px;height:32px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=a' border='0' alt='Buy Me a Coffee' /></a>
|
3
3
|
|
4
|
-
A collection of helpful methods and monkey patches for Objects, Strings, Enumerables, Arrays, Hash, Dates, Minitest & Rails
|
4
|
+
A collection of helpful methods and monkey patches for Objects, Strings, Enumerables, Arrays, Hash, Dates, Minitest & Rails (optional)
|
5
5
|
|
6
6
|
The difference between this library and others is that all monkey patching is performed in an opt-in way because you shouldnt be using methods you dont know about anyways.
|
7
7
|
|
@@ -13,99 +13,89 @@ For applicable methods I have placed the implementation inside the Rearmed modul
|
|
13
13
|
gem 'rearmed'
|
14
14
|
```
|
15
15
|
|
16
|
-
Run `rails g rearmed:setup` to create a settings files in `config/initializers/rearmed.rb` where you can opt-in to the monkey patches available in the library. Set these values to true if you want to enable the applicable monkey patch.
|
16
|
+
Run `rails g rearmed:setup` to create a settings files in `config/initializers/rearmed.rb` where you can opt-in to the monkey patches available in the library. Set these values to true if you want to enable the applicable monkey patch. If your not using Rails then just copy config this into your file and start from there.
|
17
17
|
|
18
18
|
```ruby
|
19
19
|
# config/initializers/rearmed.rb
|
20
20
|
|
21
21
|
Rearmed.enabled_patches = {
|
22
|
-
rails_4: {
|
23
|
-
or: false,
|
24
|
-
link_to_confirm: false
|
25
|
-
},
|
26
|
-
rails_3: {
|
27
|
-
pluck: false,
|
28
|
-
update_columns: false,
|
29
|
-
all: false
|
30
|
-
},
|
31
|
-
rails: {
|
32
|
-
pluck_to_hash: false,
|
33
|
-
pluck_to_struct: false,
|
34
|
-
find_or_create: false,
|
35
|
-
find_duplicates: false,
|
36
|
-
newest: false,
|
37
|
-
reset_table: false,
|
38
|
-
reset_auto_increment: false,
|
39
|
-
find_relation_each: false,
|
40
|
-
find_in_relation_batches: false,
|
41
|
-
},
|
42
|
-
string: {
|
43
|
-
valid_integer: false,
|
44
|
-
valid_float: false,
|
45
|
-
to_bool: false,
|
46
|
-
starts_with: false,
|
47
|
-
begins_with: false,
|
48
|
-
ends_with: false
|
49
|
-
},
|
50
|
-
hash: {
|
51
|
-
only: false,
|
52
|
-
dig: false,
|
53
|
-
compact: false
|
54
|
-
},
|
55
22
|
array: {
|
56
23
|
dig: false,
|
57
24
|
delete_first: false,
|
58
25
|
not_empty: false
|
59
26
|
},
|
27
|
+
date: {
|
28
|
+
now: false
|
29
|
+
},
|
60
30
|
enumerable: {
|
61
31
|
natural_sort: false,
|
62
32
|
natural_sort_by: false
|
63
33
|
},
|
34
|
+
hash: {
|
35
|
+
compact: false,
|
36
|
+
dig: false,
|
37
|
+
join: false,
|
38
|
+
only: false,
|
39
|
+
to_struct: false
|
40
|
+
},
|
64
41
|
object: {
|
65
42
|
in: false,
|
66
43
|
not_nil: false
|
67
44
|
},
|
68
|
-
|
69
|
-
|
45
|
+
string: {
|
46
|
+
begins_with: false,
|
47
|
+
ends_with: false,
|
48
|
+
starts_with: false,
|
49
|
+
to_bool: false,
|
50
|
+
valid_float: false,
|
51
|
+
valid_integer: false
|
70
52
|
},
|
71
53
|
minitest: {
|
72
54
|
assert_changed: false,
|
73
55
|
assert_not_changed: false
|
56
|
+
},
|
57
|
+
rails: {
|
58
|
+
find_duplicates: false,
|
59
|
+
find_in_relation_batches: false,
|
60
|
+
find_or_create: false,
|
61
|
+
find_relation_each: false,
|
62
|
+
newest: false,
|
63
|
+
pluck_to_hash: false,
|
64
|
+
pluck_to_struct: false,
|
65
|
+
reset_auto_increment: false,
|
66
|
+
reset_table: false
|
67
|
+
},
|
68
|
+
rails_4: {
|
69
|
+
link_to_confirm: false,
|
70
|
+
or: false
|
71
|
+
},
|
72
|
+
rails_3: {
|
73
|
+
all: false,
|
74
|
+
pluck: false,
|
75
|
+
update_columns: false
|
74
76
|
}
|
75
77
|
}
|
76
78
|
|
77
|
-
require 'rearmed/apply_patches'
|
78
|
-
```
|
79
79
|
|
80
|
-
|
81
|
-
```ruby
|
82
|
-
my_var.not_nil?
|
83
|
-
|
84
|
-
# Only for non-Rails environments, as Rails already has this method
|
85
|
-
my_var.in?([1,2,3])
|
86
|
-
my_var.in?(1,2,3) # or with splat arguments
|
80
|
+
require 'rearmed/apply_patches'
|
87
81
|
```
|
88
82
|
|
89
|
-
###
|
83
|
+
### Array Methods
|
90
84
|
```ruby
|
91
|
-
|
92
|
-
#
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
# or without monkey patch: Rearmed.to_bool('true')
|
85
|
+
array = [1,2,1,4,1]
|
86
|
+
array.delete_first(1) # => 1
|
87
|
+
puts array #=> [2,1,4,1]
|
88
|
+
array.delete_first{|x| 1 == x} # => 1
|
89
|
+
puts array # => [2,4,1]
|
90
|
+
array.delete_first # => 2
|
91
|
+
puts array # => [4,1]
|
99
92
|
|
100
|
-
|
101
|
-
'foo'.starts_with?('fo') # => true
|
102
|
-
'foo'.begins_with?('fo') # => true
|
103
|
-
'bar'.ends_with?('ar') # => true
|
104
|
-
```
|
93
|
+
array.not_empty? # => true
|
105
94
|
|
106
|
-
|
107
|
-
|
108
|
-
|
95
|
+
# Only available on array and hash in Ruby 2.2.x or below
|
96
|
+
items = [{foo: ['foo','bar']}, {test: 'thing'}]
|
97
|
+
items.dig(0, :foo, 1) # => 'bar'
|
98
|
+
# or without monkey patch: Rearmed.dig(items, 0, :foo, 1)
|
109
99
|
```
|
110
100
|
|
111
101
|
### Enumerable Methods (Array, Hash, etc.)
|
@@ -118,6 +108,27 @@ items.natural_sort(reverse: true) # because natural_sort does not accept a block
|
|
118
108
|
items = [{version: "1.1"}, {version: "1.11"}, {version: "1.2"}]
|
119
109
|
items.natural_sort_by{|x| x[:version]}
|
120
110
|
# or without monkey patch: Rearmed.natural_sort_by(items){|x| x[:version]}
|
111
|
+
```
|
112
|
+
|
113
|
+
### Date
|
114
|
+
```ruby
|
115
|
+
Date.now
|
116
|
+
```
|
117
|
+
|
118
|
+
### Hash Methods
|
119
|
+
```ruby
|
120
|
+
my_hash.compact
|
121
|
+
my_hash.compact!
|
122
|
+
|
123
|
+
hash.join{|k,v| "#{k}: #{v}\n"}
|
124
|
+
|
125
|
+
hash = {foo: 'foo', bar: 'bar', other: 'other'}
|
126
|
+
hash.only(:foo, :bar) # => {foo: 'foo'}
|
127
|
+
# or without monkey patch: Rearmed.only(hash, :foo, :bar)
|
128
|
+
|
129
|
+
hash.only!(:foo, :bar)
|
130
|
+
|
131
|
+
hash.to_struct
|
121
132
|
|
122
133
|
# Only available on array and hash in Ruby 2.2.x or below
|
123
134
|
items = [{foo: ['foo','bar']}, {test: 'thing'}]
|
@@ -125,29 +136,45 @@ items.dig(0, :foo, 1) # => 'bar'
|
|
125
136
|
# or without monkey patch: Rearmed.dig(items, 0, :foo, 1)
|
126
137
|
```
|
127
138
|
|
128
|
-
###
|
139
|
+
### Object
|
129
140
|
```ruby
|
130
|
-
|
131
|
-
array.delete_first(1) # => 1
|
132
|
-
puts array #=> [2,1,4,1]
|
133
|
-
array.delete_first{|x| 1 == x} # => 1
|
134
|
-
puts array # => [2,4,1]
|
135
|
-
array.delete_first # => 2
|
136
|
-
puts array # => [4,1]
|
141
|
+
my_var.not_nil?
|
137
142
|
|
138
|
-
|
143
|
+
# Only for non-Rails environments, as Rails already has this method
|
144
|
+
my_var.in?([1,2,3])
|
145
|
+
my_var.in?(1,2,3) # or with splat arguments
|
139
146
|
```
|
140
147
|
|
141
|
-
###
|
148
|
+
### String
|
142
149
|
```ruby
|
143
|
-
|
144
|
-
|
145
|
-
# or without monkey patch: Rearmed.only(hash, :foo, :bar)
|
150
|
+
'123'.valid_integer?
|
151
|
+
# or without monkey patch: Rearmed.valid_integer?('123')
|
146
152
|
|
147
|
-
|
153
|
+
'123.123'.valid_float?
|
154
|
+
# or without monkey patch: Rearmed.valid_float?('123.123')
|
148
155
|
|
149
|
-
|
150
|
-
|
156
|
+
'true'.to_bool
|
157
|
+
# or without monkey patch: Rearmed.to_bool('true')
|
158
|
+
|
159
|
+
# alias of start_with? and end_with? to have more sensible method names
|
160
|
+
'foo'.starts_with?('fo') # => true
|
161
|
+
'foo'.begins_with?('fo') # => true
|
162
|
+
'bar'.ends_with?('ar') # => true
|
163
|
+
```
|
164
|
+
|
165
|
+
### Minitest Methods
|
166
|
+
```ruby
|
167
|
+
assert_changed 'user.name' do
|
168
|
+
user.name = "Bob"
|
169
|
+
end
|
170
|
+
|
171
|
+
assert_not_changed -> { user.name } do
|
172
|
+
user.update(user_params)
|
173
|
+
end
|
174
|
+
|
175
|
+
assert_not_changed lambda{ user.name } do
|
176
|
+
user.update(user_params)
|
177
|
+
end
|
151
178
|
```
|
152
179
|
|
153
180
|
### Rails
|
@@ -189,13 +216,15 @@ Post.find_relation_each # this returns a relation instead of an array
|
|
189
216
|
|
190
217
|
##### Rails 4.x Backports
|
191
218
|
```ruby
|
219
|
+
# returns to rails 3 behaviour of allowing confirm attribute as well as data-confirm
|
220
|
+
= link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?"
|
221
|
+
|
222
|
+
# This version of `or` behaves way nicer than the one implemented in Rails 5, it allows you to do what you need.
|
223
|
+
# However this patch does not work in Rails 5+
|
192
224
|
Post.where(name: 'foo').or.where(content: 'bar')
|
193
225
|
Post.where(name: 'foo').or.my_custom_scope
|
194
226
|
Post.where(name: 'foo').or(Post.where(content: 'bar'))
|
195
227
|
Post.where(name: 'foo).or(content: 'bar')
|
196
|
-
|
197
|
-
= link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?"
|
198
|
-
# returns to rails 3 behaviour of allowing confirm attribute as well as data-confirm
|
199
228
|
```
|
200
229
|
|
201
230
|
##### Rails 3.x Backports
|
@@ -208,21 +237,6 @@ my_hash.compact # See Hash methods above
|
|
208
237
|
my_hash.compact!
|
209
238
|
```
|
210
239
|
|
211
|
-
### Minitest Method
|
212
|
-
```ruby
|
213
|
-
assert_changed 'user.name' do
|
214
|
-
user.name = "Bob"
|
215
|
-
end
|
216
|
-
|
217
|
-
assert_not_changed -> { user.name } do
|
218
|
-
user.update(user_params)
|
219
|
-
end
|
220
|
-
|
221
|
-
assert_not_changed lambda{ user.name } do
|
222
|
-
user.update(user_params)
|
223
|
-
end
|
224
|
-
```
|
225
|
-
|
226
240
|
# Contributing / Todo
|
227
241
|
If you want to request a method please raise an issue and we can discuss the implementation.
|
228
242
|
|
@@ -230,7 +244,6 @@ If you want to contribute here are a couple of things you could do:
|
|
230
244
|
|
231
245
|
- Add Tests for Rails methods
|
232
246
|
- Get the `natural_sort` method to accept a block
|
233
|
-
- Get the `assert_changed` and `assert_not_changed` method to accept a String with the variable name similar to Rails ``
|
234
247
|
|
235
248
|
|
236
249
|
# Credits
|
data/Rakefile
CHANGED
@@ -10,4 +10,24 @@ task :test do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
task :console do
|
14
|
+
require 'rearmed'
|
15
|
+
Rearmed.enabled_patches = {
|
16
|
+
array: true,
|
17
|
+
hash: true,
|
18
|
+
object: true,
|
19
|
+
string: true,
|
20
|
+
date: true,
|
21
|
+
enumerable: true,
|
22
|
+
rails_3: true,
|
23
|
+
rails_4: true,
|
24
|
+
rails: true,
|
25
|
+
minitest: true
|
26
|
+
}
|
27
|
+
require 'rearmed/apply_patches'
|
28
|
+
|
29
|
+
require 'irb'
|
30
|
+
binding.irb
|
31
|
+
end
|
32
|
+
|
13
33
|
task default: :test
|
@@ -5,61 +5,7 @@ module Rearmed
|
|
5
5
|
|
6
6
|
def setup
|
7
7
|
create_file "config/initializers/rearmed.rb", <<eos
|
8
|
-
Rearmed.enabled_patches = {
|
9
|
-
rails_4: {
|
10
|
-
or: false,
|
11
|
-
link_to_confirm: false
|
12
|
-
},
|
13
|
-
rails_3: {
|
14
|
-
pluck: false,
|
15
|
-
update_columns: false,
|
16
|
-
all: false
|
17
|
-
},
|
18
|
-
rails: {
|
19
|
-
pluck_to_hash: false,
|
20
|
-
pluck_to_struct: false,
|
21
|
-
find_or_create: false,
|
22
|
-
find_duplicates: false,
|
23
|
-
newest: false,
|
24
|
-
reset_table: false,
|
25
|
-
reset_auto_increment: false,
|
26
|
-
find_relation_each: false,
|
27
|
-
find_in_relation_batches: false,
|
28
|
-
},
|
29
|
-
string: {
|
30
|
-
valid_integer: false,
|
31
|
-
valid_float: false,
|
32
|
-
to_bool: false,
|
33
|
-
starts_with: false,
|
34
|
-
begins_with: false,
|
35
|
-
ends_with: false,
|
36
|
-
},
|
37
|
-
hash: {
|
38
|
-
only: false,
|
39
|
-
dig: false,
|
40
|
-
compact: false,
|
41
|
-
},
|
42
|
-
array: {
|
43
|
-
dig: false,
|
44
|
-
delete_first: false,
|
45
|
-
not_empty: false
|
46
|
-
},
|
47
|
-
enumerable: {
|
48
|
-
natural_sort: false,
|
49
|
-
natural_sort_by: false
|
50
|
-
},
|
51
|
-
object: {
|
52
|
-
in: false,
|
53
|
-
not_nil: false
|
54
|
-
},
|
55
|
-
date: {
|
56
|
-
now: false
|
57
|
-
},
|
58
|
-
minitest: {
|
59
|
-
assert_changed: false,
|
60
|
-
assert_not_changed: false
|
61
|
-
}
|
62
|
-
}
|
8
|
+
Rearmed.enabled_patches = #{File.read(File.join(File.dirname(__FILE__), '../../rearmed/default_enabled_patches.hash'))}
|
63
9
|
|
64
10
|
require 'rearmed/apply_patches'
|
65
11
|
eos
|
data/lib/rearmed.rb
CHANGED
@@ -1,59 +1,11 @@
|
|
1
|
+
require 'rearmed/version'
|
2
|
+
|
3
|
+
require 'rearmed/methods'
|
4
|
+
require 'rearmed/exceptions'
|
5
|
+
|
1
6
|
module Rearmed
|
2
7
|
|
3
|
-
@enabled_patches =
|
4
|
-
rails_4: {
|
5
|
-
or: false,
|
6
|
-
link_to_confirm: false
|
7
|
-
},
|
8
|
-
rails_3: {
|
9
|
-
pluck: false,
|
10
|
-
update_columns: false,
|
11
|
-
all: false
|
12
|
-
},
|
13
|
-
rails: {
|
14
|
-
pluck_to_hash: false,
|
15
|
-
pluck_to_struct: false,
|
16
|
-
find_or_create: false,
|
17
|
-
find_duplicates: false,
|
18
|
-
reset_table: false,
|
19
|
-
reset_auto_increment: false,
|
20
|
-
find_relation_each: false,
|
21
|
-
find_in_relation_batches: false,
|
22
|
-
},
|
23
|
-
string: {
|
24
|
-
valid_integer: false,
|
25
|
-
valid_float: false,
|
26
|
-
to_bool: false,
|
27
|
-
starts_with: false,
|
28
|
-
begins_with: false,
|
29
|
-
ends_with: false
|
30
|
-
},
|
31
|
-
hash: {
|
32
|
-
only: false,
|
33
|
-
dig: false,
|
34
|
-
compact: false
|
35
|
-
},
|
36
|
-
array: {
|
37
|
-
dig: false,
|
38
|
-
delete_first: false,
|
39
|
-
not_empty: false
|
40
|
-
},
|
41
|
-
enumerable: {
|
42
|
-
natural_sort: false,
|
43
|
-
natural_sort_by: false
|
44
|
-
},
|
45
|
-
object: {
|
46
|
-
in: false,
|
47
|
-
not_nil: false
|
48
|
-
},
|
49
|
-
date: {
|
50
|
-
now: false
|
51
|
-
},
|
52
|
-
minitest: {
|
53
|
-
assert_changed: false,
|
54
|
-
assert_not_changed: false
|
55
|
-
}
|
56
|
-
}
|
8
|
+
@enabled_patches = eval(File.read(File.join(File.dirname(__FILE__), 'rearmed/default_enabled_patches.hash')))
|
57
9
|
|
58
10
|
def self.enabled_patches=(val)
|
59
11
|
@enabled_patches = val
|
@@ -63,105 +15,4 @@ module Rearmed
|
|
63
15
|
@enabled_patches
|
64
16
|
end
|
65
17
|
|
66
|
-
def self.valid_integer?(str)
|
67
|
-
str =~ /^\d*$/ ? true : false
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.valid_float?(str)
|
71
|
-
str =~ /(^(\d+)(\.)?(\d+)?$)|(^(\d+)?(\.)(\d+)$)/ ? true : false
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.to_bool(str)
|
75
|
-
if str =~ /^true$/
|
76
|
-
true
|
77
|
-
elsif str =~ /^false$/
|
78
|
-
false
|
79
|
-
else
|
80
|
-
#raise(ArgumentError.new "incorrect element #{str}")
|
81
|
-
nil
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def self.natural_sort_by(array)
|
86
|
-
array.sort_by{|x| self.naturalize_str(yield(x))}
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.natural_sort(array, options={})
|
90
|
-
if block_given?
|
91
|
-
BlockFoundError
|
92
|
-
else
|
93
|
-
array.sort do |a,b|
|
94
|
-
if options[:reverse] == true
|
95
|
-
self.naturalize_str(b.to_s) <=> self.naturalize_str(a.to_s)
|
96
|
-
else
|
97
|
-
self.naturalize_str(a.to_s) <=> self.naturalize_str(b.to_s)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.only(hash, *keys)
|
104
|
-
keys.map!{|key| hash.convert_key(key)} if hash.respond_to?(:convert_key, true)
|
105
|
-
keys.each_with_object(hash.class.new){|k, new_hash| new_hash[k] = hash[k] if hash.has_key?(k)}
|
106
|
-
end
|
107
|
-
|
108
|
-
def self.dig(collection, *values)
|
109
|
-
current_val = nil
|
110
|
-
current_collection = collection
|
111
|
-
values.each_with_index do |val,i|
|
112
|
-
if i+1 == values.length
|
113
|
-
if (current_collection.is_a?(Array) && val.is_a?(Integer)) || (current_collection.is_a?(Hash) && ['String','Symbol'].include?(val.class.name))
|
114
|
-
current_val = current_collection[val]
|
115
|
-
else
|
116
|
-
current_val = nil
|
117
|
-
end
|
118
|
-
elsif current_collection.is_a?(Array)
|
119
|
-
if val.is_a?(Integer)
|
120
|
-
current_collection = current_collection[val]
|
121
|
-
next
|
122
|
-
else
|
123
|
-
current_val = nil
|
124
|
-
break
|
125
|
-
end
|
126
|
-
elsif current_collection.is_a?(Hash)
|
127
|
-
if ['Symbol','String'].include?(val.class.name)
|
128
|
-
current_collection = current_collection[val]
|
129
|
-
next
|
130
|
-
else
|
131
|
-
current_val = nil
|
132
|
-
break
|
133
|
-
end
|
134
|
-
else
|
135
|
-
current_val = nil
|
136
|
-
break
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
return current_val
|
141
|
-
end
|
142
|
-
|
143
|
-
class BlockFoundError < StandardError
|
144
|
-
def initialize(klass=nil)
|
145
|
-
super("Rearmed doesn't yet support a block on this method.")
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
class NoArgOrBlockGivenError < StandardError
|
150
|
-
def initialize(klass=nil)
|
151
|
-
super("Must pass an argument or a block.")
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
class BothArgAndBlockError < StandardError
|
156
|
-
def initialize(klass=nil)
|
157
|
-
super("Arguments and blocks must be used seperately.")
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
private
|
162
|
-
|
163
|
-
def self.naturalize_str(str)
|
164
|
-
str.to_s.split(/(\d+)/).map{|a| a =~ /\d+/ ? a.to_i : a}
|
165
|
-
end
|
166
|
-
|
167
18
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
array: {
|
3
|
+
dig: false,
|
4
|
+
delete_first: false,
|
5
|
+
not_empty: false
|
6
|
+
},
|
7
|
+
date: {
|
8
|
+
now: false
|
9
|
+
},
|
10
|
+
enumerable: {
|
11
|
+
natural_sort: false,
|
12
|
+
natural_sort_by: false
|
13
|
+
},
|
14
|
+
hash: {
|
15
|
+
compact: false,
|
16
|
+
dig: false,
|
17
|
+
join: false,
|
18
|
+
only: false,
|
19
|
+
to_struct: false
|
20
|
+
},
|
21
|
+
object: {
|
22
|
+
in: false,
|
23
|
+
not_nil: false
|
24
|
+
},
|
25
|
+
string: {
|
26
|
+
begins_with: false,
|
27
|
+
ends_with: false,
|
28
|
+
starts_with: false,
|
29
|
+
to_bool: false,
|
30
|
+
valid_float: false,
|
31
|
+
valid_integer: false
|
32
|
+
},
|
33
|
+
minitest: {
|
34
|
+
assert_changed: false,
|
35
|
+
assert_not_changed: false
|
36
|
+
},
|
37
|
+
rails: {
|
38
|
+
find_duplicates: false,
|
39
|
+
find_in_relation_batches: false,
|
40
|
+
find_or_create: false,
|
41
|
+
find_relation_each: false,
|
42
|
+
newest: false,
|
43
|
+
pluck_to_hash: false,
|
44
|
+
pluck_to_struct: false,
|
45
|
+
reset_auto_increment: false,
|
46
|
+
reset_table: false
|
47
|
+
},
|
48
|
+
rails_4: {
|
49
|
+
link_to_confirm: false,
|
50
|
+
or: false
|
51
|
+
},
|
52
|
+
rails_3: {
|
53
|
+
all: false,
|
54
|
+
pluck: false,
|
55
|
+
update_columns: false
|
56
|
+
}
|
57
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Rearmed
|
2
|
+
module Exceptions
|
3
|
+
|
4
|
+
class BlockFoundError < StandardError
|
5
|
+
def initialize(klass=nil)
|
6
|
+
super("Rearmed doesn't yet support a block on this method.")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class NoArgOrBlockGivenError < StandardError
|
11
|
+
def initialize(klass=nil)
|
12
|
+
super("Must pass an argument or a block.")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class BothArgAndBlockError < StandardError
|
17
|
+
def initialize(klass=nil)
|
18
|
+
super("Arguments and blocks must be used seperately.")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Rearmed
|
2
|
+
|
3
|
+
def self.dig(collection, *values)
|
4
|
+
current_val = nil
|
5
|
+
current_collection = collection
|
6
|
+
values.each_with_index do |val,i|
|
7
|
+
if i+1 == values.length
|
8
|
+
if (current_collection.is_a?(Array) && val.is_a?(Integer)) || (current_collection.is_a?(Hash) && ['String','Symbol'].include?(val.class.name))
|
9
|
+
current_val = current_collection[val]
|
10
|
+
else
|
11
|
+
current_val = nil
|
12
|
+
end
|
13
|
+
elsif current_collection.is_a?(Array)
|
14
|
+
if val.is_a?(Integer)
|
15
|
+
current_collection = current_collection[val]
|
16
|
+
next
|
17
|
+
else
|
18
|
+
current_val = nil
|
19
|
+
break
|
20
|
+
end
|
21
|
+
elsif current_collection.is_a?(Hash)
|
22
|
+
if ['Symbol','String'].include?(val.class.name)
|
23
|
+
current_collection = current_collection[val]
|
24
|
+
next
|
25
|
+
else
|
26
|
+
current_val = nil
|
27
|
+
break
|
28
|
+
end
|
29
|
+
else
|
30
|
+
current_val = nil
|
31
|
+
break
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
return current_val
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.join(hash, delimiter=', ', &block)
|
39
|
+
unless block_given?
|
40
|
+
block = -> (k,v) {
|
41
|
+
"#{k}: #{v}"
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
str = ""
|
46
|
+
|
47
|
+
hash.each_with_index do |(k,v), i|
|
48
|
+
val = block.call(k,v)
|
49
|
+
unless val.is_a?(String)
|
50
|
+
val = val.to_s
|
51
|
+
end
|
52
|
+
str << val
|
53
|
+
|
54
|
+
if i+1 < hash.length
|
55
|
+
str << delimiter
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
return str
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.natural_sort_by(array)
|
63
|
+
array.sort_by{|x| self.naturalize_str(yield(x))}
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.natural_sort(array, options={})
|
67
|
+
if block_given?
|
68
|
+
Rearmed::Exceptions::BlockFoundError
|
69
|
+
else
|
70
|
+
array.sort do |a,b|
|
71
|
+
if options[:reverse] == true
|
72
|
+
self.naturalize_str(b.to_s) <=> self.naturalize_str(a.to_s)
|
73
|
+
else
|
74
|
+
self.naturalize_str(a.to_s) <=> self.naturalize_str(b.to_s)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.only(hash, *keys)
|
81
|
+
keys.map!{|key| hash.convert_key(key)} if hash.respond_to?(:convert_key, true)
|
82
|
+
keys.each_with_object(hash.class.new){|k, new_hash| new_hash[k] = hash[k] if hash.has_key?(k)}
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.to_bool(str)
|
86
|
+
if str =~ /^(true|1|t|T)$/
|
87
|
+
true
|
88
|
+
elsif str =~ /^(false|0|f|F)$/
|
89
|
+
false
|
90
|
+
else
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.valid_integer?(str)
|
96
|
+
str =~ /^\d*$/ ? true : false
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.valid_float?(str)
|
100
|
+
str =~ /(^(\d+)(\.)?(\d+)?$)|(^(\d+)?(\.)(\d+)$)/ ? true : false
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def self.naturalize_str(str)
|
106
|
+
str.to_s.split(/(\d+)/).map{|a| a =~ /\d+/ ? a.to_i : a}
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -10,7 +10,7 @@ Array.module_eval do
|
|
10
10
|
if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :delete_first)
|
11
11
|
def delete_first(item=(no_arg_passed = true; nil))
|
12
12
|
if block_given? && !no_arg_passed
|
13
|
-
raise BothArgAndBlockError
|
13
|
+
raise Rearmed::Exceptions::BothArgAndBlockError
|
14
14
|
elsif block_given?
|
15
15
|
self.delete_at(self.index{|x| yield(x)} || self.length)
|
16
16
|
elsif item || !no_arg_passed
|
@@ -12,6 +12,22 @@ Hash.class_eval do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
if RUBY_VERSION.to_f < 2.3 && hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :dig)
|
16
|
+
def dig(*args)
|
17
|
+
Rearmed.dig(self, *args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :join)
|
22
|
+
def join(delimiter=', ', &block)
|
23
|
+
if block_given?
|
24
|
+
Rearmed.join(self, delimiter, &block)
|
25
|
+
else
|
26
|
+
Rearmed.join(self, delimiter)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
15
31
|
if hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :only)
|
16
32
|
def only(*keys)
|
17
33
|
Rearmed.only(self, *keys)
|
@@ -26,9 +42,9 @@ Hash.class_eval do
|
|
26
42
|
end
|
27
43
|
end
|
28
44
|
|
29
|
-
if
|
30
|
-
def
|
31
|
-
|
45
|
+
if hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :to_struct)
|
46
|
+
def to_struct
|
47
|
+
Struct.new(*keys).new(*values)
|
32
48
|
end
|
33
49
|
end
|
34
50
|
end
|
@@ -87,8 +87,8 @@ if defined?(ActiveRecord)
|
|
87
87
|
end
|
88
88
|
|
89
89
|
options[:columns] ||= self.column_names.reject{|x| [self.primary_key, :created_at, :updated_at, :deleted_at].include?(x)}
|
90
|
-
|
91
|
-
|
90
|
+
|
91
|
+
duplicates = self.select("#{options[:columns].join(', ')}, COUNT(*)").group(options[:columns]).having("COUNT(*) > 1")
|
92
92
|
|
93
93
|
if options[:delete]
|
94
94
|
if options[:delete] == true
|
@@ -101,9 +101,26 @@ if defined?(ActiveRecord)
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
|
104
|
+
if options[:delete][:keep] == :last
|
105
|
+
duplicates.reverse!
|
106
|
+
end
|
107
|
+
|
108
|
+
used = []
|
109
|
+
duplicates.reject! do |x|
|
110
|
+
attrs = x.attributes.slice(*options[:columns].collect(&:to_s))
|
111
|
+
|
112
|
+
if used.include?(attrs)
|
113
|
+
return false
|
114
|
+
else
|
115
|
+
used.push attrs
|
116
|
+
return true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
used = nil
|
105
120
|
|
106
121
|
if options[:delete][:delete_method].to_sym == :delete
|
122
|
+
duplicates = self.where(id: duplicates.collect(&:id))
|
123
|
+
|
107
124
|
if x.respond_to?(:delete_all!)
|
108
125
|
duplicates.delete_all!
|
109
126
|
else
|
@@ -120,7 +137,7 @@ if defined?(ActiveRecord)
|
|
120
137
|
end
|
121
138
|
return nil
|
122
139
|
else
|
123
|
-
return
|
140
|
+
return duplicates
|
124
141
|
end
|
125
142
|
end
|
126
143
|
end
|
@@ -222,7 +239,7 @@ if defined?(ActiveRecord)
|
|
222
239
|
while records.any?
|
223
240
|
records_size = records.size
|
224
241
|
primary_key_offset = records.last.id
|
225
|
-
raise "Primary key not included in the custom select clause" unless primary_key_offset
|
242
|
+
raise ActiveRecordError, "Primary key not included in the custom select clause" unless primary_key_offset
|
226
243
|
|
227
244
|
yield records
|
228
245
|
|
@@ -51,7 +51,7 @@ if defined?(ActiveRecord)
|
|
51
51
|
while records.any?
|
52
52
|
records_size = records.size
|
53
53
|
primary_key_offset = records.last.id
|
54
|
-
raise "Primary key not included in the custom select clause" unless primary_key_offset
|
54
|
+
raise ActiveRecordError, "Primary key not included in the custom select clause" unless primary_key_offset
|
55
55
|
|
56
56
|
yield records
|
57
57
|
|
data/lib/rearmed/version.rb
CHANGED
data/test/tc_rearmed.rb
CHANGED
@@ -137,13 +137,28 @@ class TestRearmed < MiniTest::Test
|
|
137
137
|
hash = {foo: 'foo', bar: 'bar', other: 'other'}
|
138
138
|
eql(Rearmed.only(hash, :foo, :bar), {foo: 'foo', bar: 'bar'})
|
139
139
|
|
140
|
-
|
141
140
|
hash = {foo: nil, bar: nil, other: 'other'}
|
142
141
|
eql(hash.compact, {other: 'other'})
|
143
142
|
|
144
143
|
hash = {foo: nil, bar: nil, other: 'other'}
|
145
144
|
hash.compact!
|
146
145
|
eql(hash, {other: 'other'})
|
146
|
+
|
147
|
+
hash = {foo: :bar, bar: :foo}
|
148
|
+
eql(hash.join, "foo: bar, bar: foo")
|
149
|
+
eql(hash.join('___'), "foo: bar___bar: foo")
|
150
|
+
eql(hash.join{|k,v| v}, "bar, foo")
|
151
|
+
eql(hash.join('___'){|k,v| v}, "bar___foo")
|
152
|
+
eql(Rearmed.join(hash), "foo: bar, bar: foo")
|
153
|
+
eql(Rearmed.join(hash, '___'), "foo: bar___bar: foo")
|
154
|
+
eql(Rearmed.join(hash){|k,v| v}, "bar, foo")
|
155
|
+
eql(Rearmed.join(hash, '___'){|k,v| v}, "bar___foo")
|
156
|
+
|
157
|
+
hash = {foo: :bar, bar: 'foo'}
|
158
|
+
struct = hash.to_struct
|
159
|
+
assert(struct.is_a?(Struct))
|
160
|
+
eql(struct.foo, :bar)
|
161
|
+
eql(struct.bar, 'foo')
|
147
162
|
end
|
148
163
|
|
149
164
|
def test_object
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rearmed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Weston Ganger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -66,6 +66,9 @@ files:
|
|
66
66
|
- lib/generators/rearmed/setup_generator.rb
|
67
67
|
- lib/rearmed.rb
|
68
68
|
- lib/rearmed/apply_patches.rb
|
69
|
+
- lib/rearmed/default_enabled_patches.hash
|
70
|
+
- lib/rearmed/exceptions.rb
|
71
|
+
- lib/rearmed/methods.rb
|
69
72
|
- lib/rearmed/monkey_patches/array.rb
|
70
73
|
- lib/rearmed/monkey_patches/date.rb
|
71
74
|
- lib/rearmed/monkey_patches/enumerable.rb
|
@@ -97,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
100
|
version: '0'
|
98
101
|
requirements: []
|
99
102
|
rubyforge_project:
|
100
|
-
rubygems_version: 2.
|
103
|
+
rubygems_version: 2.6.8
|
101
104
|
signing_key:
|
102
105
|
specification_version: 4
|
103
106
|
summary: A collection of helpful methods and monkey patches for Objects, Strings,
|