rearmed 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +68 -20
- data/lib/generators/rearmed/setup_generator.rb +11 -4
- data/lib/rearmed/apply_patches.rb +1 -0
- data/lib/rearmed/monkey_patches/array.rb +3 -3
- data/lib/rearmed/monkey_patches/date.rb +1 -1
- data/lib/rearmed/monkey_patches/enumerable.rb +2 -2
- data/lib/rearmed/monkey_patches/hash.rb +13 -2
- data/lib/rearmed/monkey_patches/object.rb +2 -2
- data/lib/rearmed/monkey_patches/rails.rb +109 -5
- data/lib/rearmed/monkey_patches/rails_3.rb +3 -17
- data/lib/rearmed/monkey_patches/rails_4.rb +4 -4
- data/lib/rearmed/monkey_patches/string.rb +15 -4
- data/lib/rearmed/version.rb +1 -1
- data/test/tc_rearmed.rb +201 -17
- 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: f2c29c181ff21a0d8d827e5ddc041a24ffdf27e2
|
4
|
+
data.tar.gz: 720e02b98600437a7721e8da557a9cf8a93af7b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce9ee1703ccb3d7cbd44d672e1622760026135fb32fc4e66b59009981cca2d40e31d0b19bfe1623cf1d7b3456934eee62618e2d5c018786e42a5ecd653ce1851
|
7
|
+
data.tar.gz: 4115b29b94fb22028294cdce9996f93ed7428aba08c3f487db6a4ff9c07f24775731d5c4890052ce3aeba824290cca7302ff9e06741ff0bab9c238dd453e7ad2
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
---------
|
3
3
|
|
4
|
+
- **1.1.0 - July 8, 2016**
|
5
|
+
- Add ActiveRecord `find_or_create`, `reset_table`, `reset_auto_increment`, `depupe`
|
6
|
+
- Add `starts_with?`, `begins_with?`, `ends_with?` aliases
|
7
|
+
- Major improvements to opt-in system
|
8
|
+
- Allow Hash compact work without ActiveSupport
|
9
|
+
- Only allow `in?` patch without ActiveSupport
|
10
|
+
- Move some methods to Rearmed for use outside of monkey patching
|
11
|
+
- Add test's for everything except for the Rails methods (Would love a PR for the Rails tests)
|
12
|
+
- **1.0.3 - June 20, 2016**
|
13
|
+
- Useless version update
|
14
|
+
- I Thought the `delete_first` method still wasn't fixed but my app was incorrect instead
|
15
|
+
- **1.0.2 - June 20, 2016**
|
16
|
+
- Fix array `delete_first` method
|
17
|
+
- **1.0.1 - June 17, 2016**
|
18
|
+
- Add `pluck_to_hash`
|
19
|
+
- Add `pluck_to_struct`
|
20
|
+
- Reorganize rails patches to have generic rails patches
|
4
21
|
- **1.0.0 - June 8, 2016**
|
5
22
|
- Ready for public use
|
6
23
|
- Major improvements to opt-in system
|
data/README.md
CHANGED
@@ -24,7 +24,6 @@ Rearmed.enabled_patches = {
|
|
24
24
|
link_to_confirm: false
|
25
25
|
},
|
26
26
|
rails_3: {
|
27
|
-
hash_compact: false,
|
28
27
|
pluck: false,
|
29
28
|
update_columns: false,
|
30
29
|
all: false
|
@@ -32,17 +31,25 @@ Rearmed.enabled_patches = {
|
|
32
31
|
rails: {
|
33
32
|
pluck_to_hash: false,
|
34
33
|
pluck_to_struct: false,
|
34
|
+
find_or_create: false,
|
35
|
+
reset_table: false,
|
36
|
+
reset_auto_increment: false,
|
37
|
+
dedupe: false,
|
35
38
|
find_relation_each: false,
|
36
39
|
find_in_relation_batches: false,
|
37
40
|
},
|
38
41
|
string: {
|
39
|
-
to_bool: false,
|
40
42
|
valid_integer: false,
|
41
|
-
valid_float: false
|
43
|
+
valid_float: false,
|
44
|
+
to_bool: false,
|
45
|
+
starts_with: false,
|
46
|
+
begins_with: false,
|
47
|
+
ends_with: false
|
42
48
|
},
|
43
49
|
hash: {
|
44
50
|
only: false,
|
45
|
-
dig: false
|
51
|
+
dig: false,
|
52
|
+
compact: false
|
46
53
|
},
|
47
54
|
array: {
|
48
55
|
dig: false,
|
@@ -67,6 +74,8 @@ require 'rearmed/apply_patches'
|
|
67
74
|
### Object
|
68
75
|
```ruby
|
69
76
|
my_var.not_nil?
|
77
|
+
|
78
|
+
# Only for non-Rails environments, as Rails already has this method
|
70
79
|
my_var.in?([1,2,3])
|
71
80
|
my_var.in?(1,2,3) # or with splat arguments
|
72
81
|
```
|
@@ -81,6 +90,11 @@ my_var.in?(1,2,3) # or with splat arguments
|
|
81
90
|
|
82
91
|
'true'.to_bool
|
83
92
|
# or without monkey patch: Rearmed.to_bool('true')
|
93
|
+
|
94
|
+
# alias of start_with? and end_with? to have more sensible method names
|
95
|
+
'foo'.starts_with?('fo') # => true
|
96
|
+
'foo'.begins_with?('fo') # => true
|
97
|
+
'bar'.ends_with?('ar') # => true
|
84
98
|
```
|
85
99
|
|
86
100
|
### Date
|
@@ -92,21 +106,17 @@ Date.now
|
|
92
106
|
```ruby
|
93
107
|
items = ['1.1', '1.11', '1.2']
|
94
108
|
items.natural_sort
|
95
|
-
items.natural_sort(reverse: true) # because natural_sort does not accept a block
|
109
|
+
items.natural_sort(reverse: true) # because natural_sort does not accept a block, accepting PR's on this
|
96
110
|
# or without monkey patch: Rearmed.natural_sort(items) or Rearmed.natural_sort(items, reverse: true)
|
97
111
|
|
98
|
-
items = ['1.1', '1.11', '1.2']
|
99
|
-
items.natural_sort{|a,b| b <=> a}
|
100
|
-
# or without monkey patch: Rearmed.natural_sort(items){|a,b| b <=> a}
|
101
|
-
|
102
112
|
items = [{version: "1.1"}, {version: "1.11"}, {version: "1.2"}]
|
103
113
|
items.natural_sort_by{|x| x[:version]}
|
104
114
|
# or without monkey patch: Rearmed.natural_sort_by(items){|x| x[:version]}
|
105
115
|
|
106
116
|
# Only available on array and hash in Ruby 2.2.x or below
|
107
117
|
items = [{foo: ['foo','bar']}, {test: 'thing'}]
|
108
|
-
items.dig(
|
109
|
-
# or without monkey patch: Rearmed.dig(items
|
118
|
+
items.dig(0, :foo, 1) # => 'bar'
|
119
|
+
# or without monkey patch: Rearmed.dig(items, 0, :foo, 1)
|
110
120
|
```
|
111
121
|
|
112
122
|
### Array Methods
|
@@ -127,33 +137,71 @@ hash.only(:foo, :bar) # => {foo: 'foo'}
|
|
127
137
|
# or without monkey patch: Rearmed.only(hash, :foo, :bar)
|
128
138
|
|
129
139
|
hash.only!(:foo, :bar)
|
140
|
+
|
141
|
+
my_hash.compact
|
142
|
+
my_hash.compact!
|
130
143
|
```
|
131
144
|
|
132
145
|
### Rails
|
133
146
|
|
134
147
|
##### Additional ActiveRecord Methods
|
148
|
+
Note: All methods which involve deletion are compatible with Paranoia & ActsAsParanoid
|
149
|
+
|
135
150
|
```ruby
|
136
|
-
Post.
|
137
|
-
Post.
|
151
|
+
Post.pluck_to_hash(:name, :category, :id)
|
152
|
+
Post.pluck_to_struct(:name, :category, :id)
|
153
|
+
|
154
|
+
Post.find_or_create(name: 'foo', content: 'bar') # use this instead of the super confusing first_or_create method
|
155
|
+
Post.find_or_create!(name: 'foo', content: 'bar')
|
156
|
+
|
157
|
+
Post.reset_table # delete all records from table and reset autoincrement column (id), works with mysql/mariadb/postgresql/sqlite
|
158
|
+
# or with options
|
159
|
+
Post.reset_table(delete_method: :destroy) # to ensure all callbacks are fired
|
160
|
+
|
161
|
+
Post.reset_auto_increment # reset mysql/mariadb/postgresql/sqlite auto-increment column, if contains records then defaults to starting from next available number
|
162
|
+
# or with options
|
163
|
+
Post.reset_auto_increment(value: 1, column: :id) # column option is only relevant for postgresql
|
164
|
+
|
165
|
+
Post.dedupe # remove all duplicate records, defaults to all of the models column_names except timestamps
|
166
|
+
# or with options
|
167
|
+
Post.dedupe(delete_method: :destroy) # to ensure all callbacks are fired
|
168
|
+
Post.dedupe(columns: [:name, :content, :category_id]
|
169
|
+
Post.dedupe(skip_timestamps: false) # skip timestamps defaults to true (created_at, updated_at, deleted_at)
|
170
|
+
Post.dedupe(keep: :last) # Keep the last duplicate instead of the first duplicate by default
|
171
|
+
|
138
172
|
Post.find_in_relation_batches # this returns a relation instead of an array
|
139
173
|
Post.find_relation_each # this returns a relation instead of an array
|
140
174
|
```
|
141
175
|
|
176
|
+
##### Rails 4.x Backports
|
177
|
+
```ruby
|
178
|
+
Post.where(name: 'foo').or.where(content: 'bar')
|
179
|
+
Post.where(name: 'foo').or.my_custom_scope
|
180
|
+
Post.where(name: 'foo').or(Post.where(content: 'bar'))
|
181
|
+
Post.where(name: 'foo).or(content: 'bar')
|
182
|
+
|
183
|
+
= link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?"
|
184
|
+
# returns to rails 3 behaviour of allowing confirm attribute as well as data-confirm
|
185
|
+
```
|
186
|
+
|
142
187
|
##### Rails 3.x Backports
|
143
188
|
```ruby
|
144
|
-
my_hash.compact
|
145
|
-
my_hash.compact!
|
146
189
|
Post.all # Now returns AR relation
|
147
190
|
Post.first.update_columns(a: 'foo', b: 'bar')
|
148
191
|
Post.pluck(:name, :id) # adds multi column pluck support ex. => [['first', 1], ['second', 2], ['third', 3]]
|
192
|
+
|
193
|
+
my_hash.compact # See Hash methods above
|
194
|
+
my_hash.compact!
|
149
195
|
```
|
150
196
|
|
197
|
+
# Contributing / Todo
|
198
|
+
If you want to request a method please raise an issue and we can discuss the implementation.
|
199
|
+
|
200
|
+
If you want to contribute here are a couple of things you could do:
|
201
|
+
|
202
|
+
- Add Tests for Rails methods
|
203
|
+
- Get the `natural_sort` method to accept a block
|
151
204
|
|
152
|
-
##### Rails 4.x Backports
|
153
|
-
```ruby
|
154
|
-
Post.where(name: 'foo').or.where(content: 'bar')
|
155
|
-
= link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?" #returns rails 3 behaviour of allowing confirm attribute as well as data-confirm
|
156
|
-
```
|
157
205
|
|
158
206
|
# Credits
|
159
207
|
Created by Weston Ganger - @westonganger
|
@@ -11,7 +11,6 @@ Rearmed.enabled_patches = {
|
|
11
11
|
link_to_confirm: false
|
12
12
|
},
|
13
13
|
rails_3: {
|
14
|
-
hash_compact: false,
|
15
14
|
pluck: false,
|
16
15
|
update_columns: false,
|
17
16
|
all: false
|
@@ -19,17 +18,25 @@ Rearmed.enabled_patches = {
|
|
19
18
|
rails: {
|
20
19
|
pluck_to_hash: false,
|
21
20
|
pluck_to_struct: false,
|
21
|
+
find_or_create: false,
|
22
|
+
reset_table: false,
|
23
|
+
reset_auto_increment: false,
|
24
|
+
dedupe: false,
|
22
25
|
find_relation_each: false,
|
23
26
|
find_in_relation_batches: false,
|
24
27
|
},
|
25
28
|
string: {
|
26
|
-
to_bool: false,
|
27
29
|
valid_integer: false,
|
28
|
-
valid_float: false
|
30
|
+
valid_float: false,
|
31
|
+
to_bool: false,
|
32
|
+
starts_with: false,
|
33
|
+
begins_with: false,
|
34
|
+
ends_with: false,
|
29
35
|
},
|
30
36
|
hash: {
|
31
37
|
only: false,
|
32
|
-
dig: false
|
38
|
+
dig: false,
|
39
|
+
compact: false,
|
33
40
|
},
|
34
41
|
array: {
|
35
42
|
dig: false,
|
@@ -3,6 +3,7 @@ require 'rearmed/monkey_patches/string'
|
|
3
3
|
require 'rearmed/monkey_patches/array'
|
4
4
|
require 'rearmed/monkey_patches/hash'
|
5
5
|
require 'rearmed/monkey_patches/enumerable'
|
6
|
+
require 'rearmed/monkey_patches/rails'
|
6
7
|
require 'rearmed/monkey_patches/rails_3'
|
7
8
|
require 'rearmed/monkey_patches/rails_4'
|
8
9
|
require 'rearmed/monkey_patches/date'
|
@@ -1,13 +1,13 @@
|
|
1
1
|
array_enabled = Rearmed.enabled_patches[:array] == true
|
2
2
|
|
3
3
|
Array.module_eval do
|
4
|
-
if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :not_empty)
|
4
|
+
if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :not_empty)
|
5
5
|
def not_empty?
|
6
6
|
!empty?
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :delete_first)
|
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
13
|
raise BothArgAndBlockError
|
@@ -21,7 +21,7 @@ Array.module_eval do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
if RUBY_VERSION.to_f < 2.3 && array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :dig)
|
24
|
+
if RUBY_VERSION.to_f < 2.3 && array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :dig)
|
25
25
|
def dig(*args)
|
26
26
|
Rearmed.dig(self, *args)
|
27
27
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
date_enabled = Rearmed.enabled_patches[:date] == true
|
2
2
|
|
3
3
|
Date.class_eval do
|
4
|
-
if date_enabled || Rearmed.dig(Rearmed.enabled_patches, :date, :now)
|
4
|
+
if date_enabled || Rearmed.dig(Rearmed.enabled_patches, :date, :now)
|
5
5
|
def self.now
|
6
6
|
DateTime.now.to_date
|
7
7
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
enumerable_enabled = Rearmed.enabled_patches[:enumerable] == true
|
2
2
|
|
3
3
|
Enumerable.module_eval do
|
4
|
-
if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort_by)
|
4
|
+
if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort_by)
|
5
5
|
def natural_sort_by
|
6
6
|
Rearmed.natural_sort_by(self){|x| yield(x)}
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort)
|
10
|
+
if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort)
|
11
11
|
def natural_sort(options={})
|
12
12
|
if block_given?
|
13
13
|
Rearmed.natural_sort(self, options){|x| yield(x)}
|
@@ -1,7 +1,18 @@
|
|
1
1
|
hash_enabled = Rearmed.enabled_patches[:hash] == true
|
2
2
|
|
3
3
|
Hash.class_eval do
|
4
|
-
|
4
|
+
allowed = defined?(ActiveSupport) ? (ActiveSupport::VERSION::MAJOR > 3) : true
|
5
|
+
if allowed && (hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :compact))
|
6
|
+
def compact
|
7
|
+
self.select{|_, value| !value.nil?}
|
8
|
+
end
|
9
|
+
|
10
|
+
def compact!
|
11
|
+
self.reject!{|_, value| value.nil?}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :only)
|
5
16
|
def only(*keys)
|
6
17
|
Rearmed.only(self, *keys)
|
7
18
|
end
|
@@ -15,7 +26,7 @@ Hash.class_eval do
|
|
15
26
|
end
|
16
27
|
end
|
17
28
|
|
18
|
-
if RUBY_VERSION.to_f < 2.3 && hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :dig)
|
29
|
+
if RUBY_VERSION.to_f < 2.3 && hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :dig)
|
19
30
|
def dig(*args)
|
20
31
|
Rearmed.dig(self, *args)
|
21
32
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
object_enabled = Rearmed.enabled_patches[:object] == true
|
2
2
|
|
3
3
|
Object.class_eval do
|
4
|
-
if object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :not_nil)
|
4
|
+
if object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :not_nil)
|
5
5
|
def not_nil?
|
6
6
|
!nil?
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
if object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :in)
|
10
|
+
if !defined?(ActiveSupport) && (object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :in))
|
11
11
|
def in?(array, *more)
|
12
12
|
if !more.empty?
|
13
13
|
array = [array, *more]
|
@@ -2,8 +2,108 @@ enabled = Rearmed.enabled_patches[:rails] == true
|
|
2
2
|
|
3
3
|
if defined?(ActiveRecord)
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
ActiveRecord::Base.class_eval do
|
6
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :reset_table)
|
7
|
+
def self.reset_table(opts={})
|
8
|
+
if opts[:delete_method] && opts[:delete_method].to_sym == :destroy
|
9
|
+
if self.try(:paranoid?)
|
10
|
+
self.unscoped.each do |x|
|
11
|
+
if x.respond_to?(:really_destroy!)
|
12
|
+
x.really_destroy!
|
13
|
+
else
|
14
|
+
x.destroy!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
else
|
18
|
+
self.unscoped.destroy_all
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
case self.connection.adapter_name.downcase.to_sym
|
23
|
+
when :mysql2
|
24
|
+
if !opts[:delete_method] || opts[:delete_method].to_sym != :destroy
|
25
|
+
if defined?(ActsAsParanoid) && self.try(:paranoid?)
|
26
|
+
self.unscoped.delete_all!
|
27
|
+
else
|
28
|
+
self.unscoped.delete_all
|
29
|
+
end
|
30
|
+
end
|
31
|
+
self.connection.execute("ALTER TABLE #{self.table_name} AUTO_INCREMENT = 1")
|
32
|
+
when :postgresql
|
33
|
+
self.connection.execute("TRUNCATE TABLE #{self.table_name} RESTART IDENTITY")
|
34
|
+
when :sqlite3
|
35
|
+
self.connection.execute("DELETE FROM #{self.table_name}")
|
36
|
+
self.connection.execute("DELETE FROM sqlite_sequence WHERE NAME='#{self.table_name}'")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :reset_auto_increment)
|
42
|
+
def self.reset_auto_increment(opts={})
|
43
|
+
case self.connection.adapter_name.downcase.to_sym
|
44
|
+
when :mysql2
|
45
|
+
opts[:value] = 1 if opts[:value].blank?
|
46
|
+
self.connection.execute("ALTER TABLE #{self.table_name} AUTO_INCREMENT = #{opts[:value]}")
|
47
|
+
when :postgresql
|
48
|
+
opts[:value] = 1 if opts[:value].blank?
|
49
|
+
self.connection.execute("ALTER SEQUENCE #{self.table_name}_#{opts[:column].to_s || 'id'}_seq RESTART WITH #{opts[:value]}")
|
50
|
+
when :sqlite3
|
51
|
+
opts[:value] = 0 if opts[:value].blank?
|
52
|
+
self.connection.execute("UPDATE SQLITE_SEQUENCE SET SEQ=#{opts[:value]} WHERE NAME='#{self.table_name}'")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :dedupe)
|
58
|
+
def self.dedupe(opts={})
|
59
|
+
if !opts[:columns]
|
60
|
+
opts[:columns] = self.column_names.reject{|x| x == 'id'}
|
61
|
+
end
|
62
|
+
|
63
|
+
if opts[:skip_timestamps] != false
|
64
|
+
opts[:columns].reject!{|x| ['created_at','updated_at','deleted_at'].include?(x)}
|
65
|
+
end
|
66
|
+
|
67
|
+
self.all.group_by{|model| opts[:columns].map{|x| model[x]}}.values.each do |duplicates|
|
68
|
+
(opts[:keep] && opts[:keep].to_sym == :last) ? duplicates.pop : duplicates.shift
|
69
|
+
if opts[:delete_method] && opts[:delete_method].to_sym == :destroy
|
70
|
+
duplicates.each do |x|
|
71
|
+
if x.respond_to?(:really_destroy!)
|
72
|
+
x.really_destroy!
|
73
|
+
else
|
74
|
+
x.destroy!
|
75
|
+
end
|
76
|
+
end
|
77
|
+
else
|
78
|
+
if defined?(ActsAsParanoid) && self.try(:paranoid?)
|
79
|
+
self.unscoped.where(id: duplicates.collect(&:id)).delete_all!
|
80
|
+
else
|
81
|
+
self.unscoped.where(id: duplicates.collect(&:id)).delete_all
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :find_or_create)
|
89
|
+
def self.find_or_create(attrs={}, save_opts={})
|
90
|
+
unless self.where(attrs).limit(1).first
|
91
|
+
x = self.class.new(attrs)
|
92
|
+
x.save(save_opts)
|
93
|
+
return t
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.find_or_create!(attrs={}, save_opts={})
|
98
|
+
unless self.where(attrs).limit(1).first
|
99
|
+
x = self.class.new(attrs)
|
100
|
+
x.save!(save_opts)
|
101
|
+
return t
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :pluck_to_hash)
|
7
107
|
def self.pluck_to_hash(*keys)
|
8
108
|
hash_type = keys[-1].is_a?(Hash) ? keys.pop.fetch(:hash_type, HashWithIndifferentAccess) : HashWithIndifferentAccess
|
9
109
|
block_given = block_given?
|
@@ -15,7 +115,9 @@ if defined?(ActiveRecord)
|
|
15
115
|
block_given ? yield(value) : value
|
16
116
|
end
|
17
117
|
end
|
118
|
+
end
|
18
119
|
|
120
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :pluck_to_struct)
|
19
121
|
def self.pluck_to_struct(*keys)
|
20
122
|
struct_type = keys[-1].is_a?(Hash) ? keys.pop.fetch(:struct_type, Struct) : Struct
|
21
123
|
block_given = block_given?
|
@@ -28,9 +130,11 @@ if defined?(ActiveRecord)
|
|
28
130
|
block_given ? yield(value) : value
|
29
131
|
end
|
30
132
|
end
|
133
|
+
end
|
31
134
|
|
32
|
-
|
135
|
+
private
|
33
136
|
|
137
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :pluck_to_hash) || Rearmed.dig(Rearmed.enabled_patches, :rails, :pluck_to_struct)
|
34
138
|
def self.format_keys(keys)
|
35
139
|
if keys.blank?
|
36
140
|
[column_names, column_names]
|
@@ -52,7 +156,7 @@ if defined?(ActiveRecord)
|
|
52
156
|
end
|
53
157
|
|
54
158
|
ActiveRecord::Batches.module_eval do
|
55
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :find_in_relation_batches)
|
159
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :find_in_relation_batches)
|
56
160
|
def find_in_relation_batches(options = {})
|
57
161
|
options.assert_valid_keys(:start, :batch_size)
|
58
162
|
|
@@ -89,7 +193,7 @@ if defined?(ActiveRecord)
|
|
89
193
|
end
|
90
194
|
end
|
91
195
|
|
92
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :find_relation_each)
|
196
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails, :find_relation_each)
|
93
197
|
def find_relation_each(options = {})
|
94
198
|
if block_given?
|
95
199
|
find_in_relation_batches(options) do |records|
|
@@ -1,22 +1,8 @@
|
|
1
1
|
enabled = Rearmed.enabled_patches[:rails_3] == true
|
2
2
|
|
3
|
-
if defined?(ActiveSupport) && ActiveSupport::VERSION::MAJOR < 4
|
4
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_3, :hash_compact) == true
|
5
|
-
Hash.class_eval do
|
6
|
-
def compact
|
7
|
-
self.select{|_, value| !value.nil?}
|
8
|
-
end
|
9
|
-
|
10
|
-
def compact!
|
11
|
-
self.reject!{|_, value| value.nil?}
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
3
|
if defined?(ActiveRecord) && ActiveRecord::VERSION::MAJOR < 4
|
18
4
|
|
19
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_3, :all)
|
5
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_3, :all)
|
20
6
|
ActiveRecord::FinderMethods.module_eval do
|
21
7
|
def all(*args)
|
22
8
|
args.any? ? apply_finder_options(args.first) : self
|
@@ -24,7 +10,7 @@ if defined?(ActiveRecord) && ActiveRecord::VERSION::MAJOR < 4
|
|
24
10
|
end
|
25
11
|
end
|
26
12
|
|
27
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_3, :update_columns)
|
13
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_3, :update_columns)
|
28
14
|
ActiveRecord::Persistence::ClassMethods.module_eval do
|
29
15
|
def update_columns(attributes)
|
30
16
|
raise ActiveRecordError, "cannot update a new record" if new_record?
|
@@ -45,7 +31,7 @@ if defined?(ActiveRecord) && ActiveRecord::VERSION::MAJOR < 4
|
|
45
31
|
end
|
46
32
|
end
|
47
33
|
|
48
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_3, :pluck)
|
34
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_3, :pluck)
|
49
35
|
ActiveRecord::Relation.class_eval do
|
50
36
|
def pluck(*args)
|
51
37
|
args.map! do |column_name|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
enabled = Rearmed.enabled_patches[:rails_4] == true
|
2
2
|
|
3
|
-
if defined?(ActionView) && enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :link_to_confirm)
|
3
|
+
if defined?(ActionView) && enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :link_to_confirm)
|
4
4
|
ActionView::Helpers::UrlHelper.module_eval do
|
5
5
|
def convert_options_to_data_attributes(options, html_options)
|
6
6
|
if html_options
|
@@ -25,7 +25,7 @@ end
|
|
25
25
|
if defined?(ActiveRecord)
|
26
26
|
|
27
27
|
ActiveRecord::Batches.module_eval do
|
28
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :find_in_relation_batches)
|
28
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :find_in_relation_batches)
|
29
29
|
def find_in_relation_batches(options = {})
|
30
30
|
options.assert_valid_keys(:start, :batch_size)
|
31
31
|
|
@@ -62,7 +62,7 @@ if defined?(ActiveRecord)
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :find_relation_each)
|
65
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :find_relation_each)
|
66
66
|
def find_relation_each(options = {})
|
67
67
|
if block_given?
|
68
68
|
find_in_relation_batches(options) do |records|
|
@@ -78,7 +78,7 @@ if defined?(ActiveRecord)
|
|
78
78
|
end
|
79
79
|
|
80
80
|
|
81
|
-
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :or)
|
81
|
+
if enabled || Rearmed.dig(Rearmed.enabled_patches, :rails_4, :or)
|
82
82
|
module ActiveRecord
|
83
83
|
module Querying
|
84
84
|
delegate :or, :to => :all
|
@@ -1,22 +1,33 @@
|
|
1
1
|
string_enabled = Rearmed.enabled_patches[:string] == true
|
2
2
|
|
3
3
|
String.class_eval do
|
4
|
-
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :valid_integer)
|
4
|
+
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :valid_integer)
|
5
5
|
def valid_integer?
|
6
6
|
Rearmed.valid_integer?(self)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :valid_float)
|
10
|
+
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :valid_float)
|
11
11
|
def valid_float?
|
12
12
|
Rearmed.valid_float?(self)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :to_bool)
|
16
|
+
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :to_bool)
|
17
17
|
def to_bool
|
18
18
|
Rearmed.to_bool(self)
|
19
19
|
end
|
20
20
|
end
|
21
|
-
end
|
22
21
|
|
22
|
+
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :starts_with)
|
23
|
+
alias_method :starts_with?, :start_with?
|
24
|
+
end
|
25
|
+
|
26
|
+
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :begins_with)
|
27
|
+
alias_method :begins_with?, :start_with?
|
28
|
+
end
|
29
|
+
|
30
|
+
if string_enabled || Rearmed.dig(Rearmed.enabled_patches, :string, :ends_with)
|
31
|
+
alias_method :ends_with?, :end_with?
|
32
|
+
end
|
33
|
+
end
|
data/lib/rearmed/version.rb
CHANGED
data/test/tc_rearmed.rb
CHANGED
@@ -1,33 +1,217 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
|
-
require 'yaml'
|
3
|
-
require 'minitest'
|
4
2
|
|
5
3
|
lib = File.expand_path('../lib', __FILE__)
|
6
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
7
|
-
|
5
|
+
|
6
|
+
require 'yaml'
|
7
|
+
require 'minitest'
|
8
|
+
|
9
|
+
require 'rearmed'
|
8
10
|
|
9
11
|
require 'minitest/autorun'
|
10
12
|
|
11
13
|
class TestRearmed < MiniTest::Test
|
12
14
|
def setup
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
Minitest::Assertions.module_eval do
|
16
|
+
alias_method :eql, :assert_equal
|
17
|
+
end
|
18
|
+
|
19
|
+
Rearmed.enabled_patches = {
|
20
|
+
array: true,
|
21
|
+
hash: true,
|
22
|
+
object: true,
|
23
|
+
string: true,
|
24
|
+
date: true,
|
25
|
+
enumerable: true,
|
26
|
+
rails_3: true,
|
27
|
+
rails_4: true,
|
28
|
+
rails: true
|
29
|
+
}
|
30
|
+
require 'rearmed/apply_patches'
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_string
|
34
|
+
# Test String Methods
|
35
|
+
str = '32'
|
36
|
+
eql(str.valid_integer?, true)
|
37
|
+
|
38
|
+
str = '32.2'
|
39
|
+
eql(str.valid_integer?, false)
|
40
|
+
|
41
|
+
str = '32a'
|
42
|
+
eql(str.valid_integer?, false)
|
43
|
+
|
44
|
+
str = '132.2'
|
45
|
+
eql(str.valid_float?, true)
|
46
|
+
|
47
|
+
str = '132.2.2'
|
48
|
+
eql(str.valid_float?, false)
|
49
|
+
|
50
|
+
str = '12.1a'
|
51
|
+
eql(str.valid_float?, false)
|
52
|
+
|
53
|
+
str = 'true'
|
54
|
+
eql(str.to_bool, true)
|
55
|
+
|
56
|
+
str = 'false'
|
57
|
+
eql(str.to_bool, false)
|
58
|
+
|
59
|
+
str = 'not true'
|
60
|
+
eql(str.to_bool, nil)
|
61
|
+
|
62
|
+
|
63
|
+
# Test Rearmed methods (just cause really)
|
64
|
+
str = 'true'
|
65
|
+
eql(Rearmed.to_bool(str), true)
|
66
|
+
|
67
|
+
str = '12'
|
68
|
+
eql(Rearmed.valid_integer?(str), true)
|
69
|
+
|
70
|
+
str = '1.2'
|
71
|
+
eql(Rearmed.valid_float?(str), true)
|
16
72
|
end
|
17
73
|
|
18
|
-
def
|
19
|
-
|
74
|
+
def test_date
|
75
|
+
Date.now
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_enumerable
|
79
|
+
items = ['1.1', '1.11', '1.2']
|
80
|
+
|
81
|
+
eql(items.natural_sort, ['1.1','1.2','1.11'])
|
82
|
+
|
83
|
+
eql(items.natural_sort(reverse: true), ['1.11','1.2','1.1'])
|
84
|
+
|
85
|
+
eql(Rearmed.natural_sort(items), ['1.1','1.2','1.11'])
|
86
|
+
|
87
|
+
eql(Rearmed.natural_sort(items, reverse: true), ['1.11','1.2','1.1'])
|
88
|
+
|
89
|
+
|
90
|
+
items = [{version: "1.1"}, {version: "1.11"}, {version: "1.2"}]
|
20
91
|
|
21
|
-
|
22
|
-
assert_equal "1.22", @array.natural_sort{|a,b| b <=> a}[0]
|
23
|
-
assert_equal "1.2", @array.natural_sort_by{|x| x}[1]
|
92
|
+
eql(items.natural_sort_by{|x| x[:version]}, [{version: "1.1"}, {version: "1.2"}, {version: "1.11"}])
|
24
93
|
|
25
|
-
|
26
|
-
|
27
|
-
|
94
|
+
eql(Rearmed.natural_sort_by(items){|x| x[:version]}, [{version: "1.1"}, {version: "1.2"}, {version: "1.11"}])
|
95
|
+
|
96
|
+
|
97
|
+
# Only available on array and hash in Ruby 2.2.x or below
|
98
|
+
array = [{foo: ['foo','bar']}, {test: 'thing'}]
|
99
|
+
|
100
|
+
eql(array.dig(0, :foo, 1), 'bar')
|
101
|
+
eql(array.dig(0, :foo, 2), nil)
|
102
|
+
|
103
|
+
eql(Rearmed.dig(array, 1, :test), 'thing')
|
104
|
+
eql(Rearmed.dig(array, 1, :bar), nil)
|
105
|
+
|
106
|
+
hash = {a: {foo: ['bar']}, b: {c: 'c'}}
|
107
|
+
|
108
|
+
eql(hash.dig(:a, :foo, 0), 'bar')
|
109
|
+
eql(Rearmed.dig(hash, :b, :c), 'c')
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_array
|
113
|
+
array = [1,3,2,1,3,4,1]
|
114
|
+
array.delete_first(3)
|
115
|
+
eql(array, [1,2,1,3,4,1])
|
116
|
+
|
117
|
+
array = [1,3,2,1,3,4,1]
|
118
|
+
array.delete_first
|
119
|
+
eql(array, [3,2,1,3,4,1])
|
120
|
+
|
121
|
+
array = [1,3,2,1,3,4,1]
|
122
|
+
array.delete_first{|x| x != 1}
|
123
|
+
eql(array, [1,2,1,3,4,1])
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_hash
|
127
|
+
hash = {foo: 'foo', bar: 'bar', other: 'other'}
|
128
|
+
eql(hash.only(:foo, :bar), {foo: 'foo', bar: 'bar'})
|
129
|
+
|
130
|
+
hash = {foo: 'foo', bar: 'bar', other: 'other'}
|
131
|
+
hash.only!(:foo, :bar)
|
132
|
+
eql(hash, {foo: 'foo', bar: 'bar'})
|
133
|
+
|
134
|
+
hash = {foo: 'foo', bar: 'bar', other: 'other'}
|
135
|
+
eql(Rearmed.only(hash, :foo, :bar), {foo: 'foo', bar: 'bar'})
|
136
|
+
|
137
|
+
|
138
|
+
hash = {foo: nil, bar: nil, other: 'other'}
|
139
|
+
eql(hash.compact, {other: 'other'})
|
140
|
+
|
141
|
+
hash = {foo: nil, bar: nil, other: 'other'}
|
142
|
+
hash.compact!
|
143
|
+
eql(hash, {other: 'other'})
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_object
|
147
|
+
str = 'test'
|
148
|
+
eql(str.not_nil?, true)
|
149
|
+
|
150
|
+
str = nil
|
151
|
+
eql(str.not_nil?, false)
|
152
|
+
|
153
|
+
str = false
|
154
|
+
eql(str.not_nil?, true)
|
155
|
+
|
156
|
+
str = 'test'
|
157
|
+
eql(str.in?(['test','abc']), true)
|
158
|
+
|
159
|
+
str = 'test'
|
160
|
+
eql(str.in?(['abc','def']), false)
|
161
|
+
|
162
|
+
str = 'test'
|
163
|
+
eql(str.in?('test','abc'), true)
|
164
|
+
|
165
|
+
str = 'test'
|
166
|
+
eql(str.in?('abc','def'), false)
|
167
|
+
|
168
|
+
str = 'test'
|
169
|
+
eql(str.in?('a test string'), true)
|
170
|
+
|
171
|
+
str = 'test'
|
172
|
+
eql(str.in?('a real string'), false)
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_general_rails
|
176
|
+
# THE MOST IMPORTANT TESTS HERE WOULD BE dedupe, reset_auto_increment, reset_table
|
177
|
+
|
178
|
+
#Post.reset_table # delete all records from table and reset autoincrement column (id), works with mysql/mariadb/postgresql/sqlite
|
179
|
+
# or with options
|
180
|
+
#Post.reset_table(delete_method: :destroy) # use destroy_all to ensure all callbacks are fired
|
181
|
+
|
182
|
+
#Post.reset_auto_increment # reset mysql/mariadb/postgresql/sqlite auto-increment column
|
183
|
+
# or with options
|
184
|
+
#Post.reset_auto_increment(value: 1, column: :id)
|
185
|
+
|
186
|
+
#Post.dedupe # remove all duplicate records, defaults to the models column_names list
|
187
|
+
# or with options
|
188
|
+
#Post.dedupe(columns: [:name, :content, :category_id])
|
189
|
+
#Post.dedupe(skip_timestamps: true)
|
190
|
+
#Post.pluck_to_hash(:name, :category, :id)
|
191
|
+
#Post.pluck_to_struct(:name, :category, :id)
|
192
|
+
|
193
|
+
#Post.find_or_create(name: 'foo', content: 'bar') # use this instead of the super confusing first_or_create method
|
194
|
+
#Post.find_or_create!(name: 'foo', content: 'bar')
|
195
|
+
|
196
|
+
#Post.find_in_relation_batches # this returns a relation instead of an array
|
197
|
+
#Post.find_relation_each # this returns a relation instead of an array
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_rails_3
|
201
|
+
#my_hash.compact
|
202
|
+
#my_hash.compact!
|
203
|
+
#Post.all # Now returns AR relation
|
204
|
+
#Post.first.update_columns(a: 'foo', b: 'bar')
|
205
|
+
#Post.pluck(:name, :id) # adds multi column pluck support ex. => [['first', 1], ['second', 2], ['third', 3]]
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_rails_4
|
209
|
+
#Post.where(name: 'foo').or.where(content: 'bar')
|
210
|
+
#Post.where(name: 'foo').or.my_custom_scope
|
211
|
+
#Post.where(name: 'foo').or(Post.where(content: 'bar'))
|
212
|
+
#Post.where(name: 'foo).or(content: 'bar')
|
28
213
|
|
29
|
-
|
30
|
-
#
|
31
|
-
#assert_equal({version: "1.2"}, @hash_array.natural_sort_by{|x| x[:version]}[1])
|
214
|
+
#= link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?"
|
215
|
+
# returns to rails 3 behaviour of allowing confirm attribute as well as data-confirm
|
32
216
|
end
|
33
217
|
end
|
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.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Weston Ganger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|