Skip to content
This repository has been archived by the owner on Oct 17, 2023. It is now read-only.

Commit

Permalink
v1.1.0
Browse files Browse the repository at this point in the history
* Add AR find_or_create, reset_table, reset_auto_increment, & dedupe. Add string starts_with?, begins_with?, & ends_with?.

* add delete_method option to reset_table method

* v1.1

* require rails patch, remove calls to reset in rails patches

* work with paranoid on reset_table

* fix dedupe method

* dedupe and fix documentation

* Update README.md

* Update README.md

* remove assert_nothing_raise
  • Loading branch information
westonganger authored Jul 9, 2016
1 parent 7e52683 commit 005dd31
Show file tree
Hide file tree
Showing 15 changed files with 451 additions and 82 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
CHANGELOG
---------

- **1.1.0 - July 8, 2016**
- Add ActiveRecord `find_or_create`, `reset_table`, `reset_auto_increment`, `depupe`
- Add `starts_with?`, `begins_with?`, `ends_with?` aliases
- Major improvements to opt-in system
- Allow Hash compact work without ActiveSupport
- Only allow `in?` patch without ActiveSupport
- Move some methods to Rearmed for use outside of monkey patching
- Add test's for everything except for the Rails methods (Would love a PR for the Rails tests)
- **1.0.3 - June 20, 2016**
- Useless version update
- I Thought the `delete_first` method still wasn't fixed but my app was incorrect instead
- **1.0.2 - June 20, 2016**
- Fix array `delete_first` method
- **1.0.1 - June 17, 2016**
- Add `pluck_to_hash`
- Add `pluck_to_struct`
- Reorganize rails patches to have generic rails patches
- **1.0.0 - June 8, 2016**
- Ready for public use
- Major improvements to opt-in system
Expand Down
88 changes: 68 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,32 @@ Rearmed.enabled_patches = {
link_to_confirm: false
},
rails_3: {
hash_compact: false,
pluck: false,
update_columns: false,
all: false
},
rails: {
pluck_to_hash: false,
pluck_to_struct: false,
find_or_create: false,
reset_table: false,
reset_auto_increment: false,
dedupe: false,
find_relation_each: false,
find_in_relation_batches: false,
},
string: {
to_bool: false,
valid_integer: false,
valid_float: false
valid_float: false,
to_bool: false,
starts_with: false,
begins_with: false,
ends_with: false
},
hash: {
only: false,
dig: false
dig: false,
compact: false
},
array: {
dig: false,
Expand All @@ -67,6 +74,8 @@ require 'rearmed/apply_patches'
### Object
```ruby
my_var.not_nil?

# Only for non-Rails environments, as Rails already has this method
my_var.in?([1,2,3])
my_var.in?(1,2,3) # or with splat arguments
```
Expand All @@ -81,6 +90,11 @@ my_var.in?(1,2,3) # or with splat arguments

'true'.to_bool
# or without monkey patch: Rearmed.to_bool('true')

# alias of start_with? and end_with? to have more sensible method names
'foo'.starts_with?('fo') # => true
'foo'.begins_with?('fo') # => true
'bar'.ends_with?('ar') # => true
```

### Date
Expand All @@ -92,21 +106,17 @@ Date.now
```ruby
items = ['1.1', '1.11', '1.2']
items.natural_sort
items.natural_sort(reverse: true) # because natural_sort does not accept a block
items.natural_sort(reverse: true) # because natural_sort does not accept a block, accepting PR's on this
# or without monkey patch: Rearmed.natural_sort(items) or Rearmed.natural_sort(items, reverse: true)

items = ['1.1', '1.11', '1.2']
items.natural_sort{|a,b| b <=> a}
# or without monkey patch: Rearmed.natural_sort(items){|a,b| b <=> a}

items = [{version: "1.1"}, {version: "1.11"}, {version: "1.2"}]
items.natural_sort_by{|x| x[:version]}
# or without monkey patch: Rearmed.natural_sort_by(items){|x| x[:version]}

# Only available on array and hash in Ruby 2.2.x or below
items = [{foo: ['foo','bar']}, {test: 'thing'}]
items.dig(1, :foo, 2) # => 'bar'
# or without monkey patch: Rearmed.dig(items){|x| x[:version]}
items.dig(0, :foo, 1) # => 'bar'
# or without monkey patch: Rearmed.dig(items, 0, :foo, 1)
```

### Array Methods
Expand All @@ -127,33 +137,71 @@ hash.only(:foo, :bar) # => {foo: 'foo'}
# or without monkey patch: Rearmed.only(hash, :foo, :bar)

hash.only!(:foo, :bar)

my_hash.compact
my_hash.compact!
```

### Rails

##### Additional ActiveRecord Methods
Note: All methods which involve deletion are compatible with Paranoia & ActsAsParanoid

```ruby
Post.all.pluck_to_hash(:name, :category, :id)
Post.all.pluck_to_struct(:name, :category, :id)
Post.pluck_to_hash(:name, :category, :id)
Post.pluck_to_struct(:name, :category, :id)

Post.find_or_create(name: 'foo', content: 'bar') # use this instead of the super confusing first_or_create method
Post.find_or_create!(name: 'foo', content: 'bar')

Post.reset_table # delete all records from table and reset autoincrement column (id), works with mysql/mariadb/postgresql/sqlite
# or with options
Post.reset_table(delete_method: :destroy) # to ensure all callbacks are fired

Post.reset_auto_increment # reset mysql/mariadb/postgresql/sqlite auto-increment column, if contains records then defaults to starting from next available number
# or with options
Post.reset_auto_increment(value: 1, column: :id) # column option is only relevant for postgresql

Post.dedupe # remove all duplicate records, defaults to all of the models column_names except timestamps
# or with options
Post.dedupe(delete_method: :destroy) # to ensure all callbacks are fired
Post.dedupe(columns: [:name, :content, :category_id]
Post.dedupe(skip_timestamps: false) # skip timestamps defaults to true (created_at, updated_at, deleted_at)
Post.dedupe(keep: :last) # Keep the last duplicate instead of the first duplicate by default

Post.find_in_relation_batches # this returns a relation instead of an array
Post.find_relation_each # this returns a relation instead of an array
```

##### Rails 4.x Backports
```ruby
Post.where(name: 'foo').or.where(content: 'bar')
Post.where(name: 'foo').or.my_custom_scope
Post.where(name: 'foo').or(Post.where(content: 'bar'))
Post.where(name: 'foo).or(content: 'bar')
= link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?"
# returns to rails 3 behaviour of allowing confirm attribute as well as data-confirm
```
##### Rails 3.x Backports
```ruby
my_hash.compact
my_hash.compact!
Post.all # Now returns AR relation
Post.first.update_columns(a: 'foo', b: 'bar')
Post.pluck(:name, :id) # adds multi column pluck support ex. => [['first', 1], ['second', 2], ['third', 3]]
my_hash.compact # See Hash methods above
my_hash.compact!
```
# Contributing / Todo
If you want to request a method please raise an issue and we can discuss the implementation.
If you want to contribute here are a couple of things you could do:
- Add Tests for Rails methods
- Get the `natural_sort` method to accept a block
##### Rails 4.x Backports
```ruby
Post.where(name: 'foo').or.where(content: 'bar')
= 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
```
# Credits
Created by Weston Ganger - @westonganger
Expand Down
15 changes: 11 additions & 4 deletions lib/generators/rearmed/setup_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,32 @@ def setup
link_to_confirm: false
},
rails_3: {
hash_compact: false,
pluck: false,
update_columns: false,
all: false
},
rails: {
pluck_to_hash: false,
pluck_to_struct: false,
find_or_create: false,
reset_table: false,
reset_auto_increment: false,
dedupe: false,
find_relation_each: false,
find_in_relation_batches: false,
},
string: {
to_bool: false,
valid_integer: false,
valid_float: false
valid_float: false,
to_bool: false,
starts_with: false,
begins_with: false,
ends_with: false,
},
hash: {
only: false,
dig: false
dig: false,
compact: false,
},
array: {
dig: false,
Expand Down
1 change: 1 addition & 0 deletions lib/rearmed/apply_patches.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'rearmed/monkey_patches/array'
require 'rearmed/monkey_patches/hash'
require 'rearmed/monkey_patches/enumerable'
require 'rearmed/monkey_patches/rails'
require 'rearmed/monkey_patches/rails_3'
require 'rearmed/monkey_patches/rails_4'
require 'rearmed/monkey_patches/date'
6 changes: 3 additions & 3 deletions lib/rearmed/monkey_patches/array.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
array_enabled = Rearmed.enabled_patches[:array] == true

Array.module_eval do
if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :not_empty) == true
if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :not_empty)
def not_empty?
!empty?
end
end

if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :delete_first) == true
if array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :delete_first)
def delete_first(item=(no_arg_passed = true; nil))
if block_given? && !no_arg_passed
raise BothArgAndBlockError
Expand All @@ -21,7 +21,7 @@ def delete_first(item=(no_arg_passed = true; nil))
end
end

if RUBY_VERSION.to_f < 2.3 && array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :dig) == true
if RUBY_VERSION.to_f < 2.3 && array_enabled || Rearmed.dig(Rearmed.enabled_patches, :array, :dig)
def dig(*args)
Rearmed.dig(self, *args)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rearmed/monkey_patches/date.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
date_enabled = Rearmed.enabled_patches[:date] == true

Date.class_eval do
if date_enabled || Rearmed.dig(Rearmed.enabled_patches, :date, :now) == true
if date_enabled || Rearmed.dig(Rearmed.enabled_patches, :date, :now)
def self.now
DateTime.now.to_date
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rearmed/monkey_patches/enumerable.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
enumerable_enabled = Rearmed.enabled_patches[:enumerable] == true

Enumerable.module_eval do
if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort_by) == true
if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort_by)
def natural_sort_by
Rearmed.natural_sort_by(self){|x| yield(x)}
end
end

if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort) == true
if enumerable_enabled || Rearmed.dig(Rearmed.enabled_patches, :enumerable, :natural_sort)
def natural_sort(options={})
if block_given?
Rearmed.natural_sort(self, options){|x| yield(x)}
Expand Down
15 changes: 13 additions & 2 deletions lib/rearmed/monkey_patches/hash.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
hash_enabled = Rearmed.enabled_patches[:hash] == true

Hash.class_eval do
if hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :only) == true
allowed = defined?(ActiveSupport) ? (ActiveSupport::VERSION::MAJOR > 3) : true
if allowed && (hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :compact))
def compact
self.select{|_, value| !value.nil?}
end

def compact!
self.reject!{|_, value| value.nil?}
end
end

if hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :only)
def only(*keys)
Rearmed.only(self, *keys)
end
Expand All @@ -15,7 +26,7 @@ def only!(*keys)
end
end

if RUBY_VERSION.to_f < 2.3 && hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :dig) == true
if RUBY_VERSION.to_f < 2.3 && hash_enabled || Rearmed.dig(Rearmed.enabled_patches, :hash, :dig)
def dig(*args)
Rearmed.dig(self, *args)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rearmed/monkey_patches/object.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
object_enabled = Rearmed.enabled_patches[:object] == true

Object.class_eval do
if object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :not_nil) == true
if object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :not_nil)
def not_nil?
!nil?
end
end

if object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :in) == true
if !defined?(ActiveSupport) && (object_enabled || Rearmed.dig(Rearmed.enabled_patches, :object, :in))
def in?(array, *more)
if !more.empty?
array = [array, *more]
Expand Down
Loading

0 comments on commit 005dd31

Please sign in to comment.