rearmed_rails 1.0.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5d2e1474fe0711ea54cf256d3954b9254c4e8e01
4
- data.tar.gz: 26d6c3cb7c20f65d5568019d4be2c4335af2dabe
2
+ SHA256:
3
+ metadata.gz: 66bf5b7b6b2a6f6cfb1697c7a05edfc21dbb27d3f3bf38ffce810fc5f2ea2b21
4
+ data.tar.gz: 5f96d7b7582e51ec05b74da7f85bc18f1eebb5f07a73a09e2375dc4fec928570
5
5
  SHA512:
6
- metadata.gz: 461717a406c59c914ad5f66fa2955efb0678aaf8926a315d733a41f134f40dfaab46433f3a923beec00dc947b626ccd2aa1def8bdfb1f841033af074f6105547
7
- data.tar.gz: aa3ce67201167bf2ba223043118fb992db82300c277c021ca14c87d76b3f90daa6aaed0ef19d5200aa63afe935a1581afb06df69efb24a3c4851968806ef829b
6
+ metadata.gz: 5153c73e99edd5ee9f010babbd24eed05640a6ba538fb3991083ec9130c6979c447763fd39cf289e9bdefedb1ae6a908aaada86f0beedecb15dc108d57fb513f
7
+ data.tar.gz: deca81c0c5c8f2c5226ab2f9d2d82abaebd8eea3d3cfac87fd8c85c54e6dee572db8f5b89073bb0e7e7877d805dea890cedb2e799b758647ba760778f6a28215
data/CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
1
  CHANGELOG
2
2
  ---------
3
3
 
4
+ - **2.0.0 - July 11, 2018**
5
+ - Change method of applying patches from `require 'rearmed_rails/apply_patches'` to `RearmedRails#apply_patches!`
6
+ - Once `apply_patches!` has been called, then `enabled_patches` cannot be changed. If it is, it will raise a `PatchesAlreadyAppliedError`
7
+ - Allow setting `:all` for `Rearmed#enabled_patches=`
8
+ - Add type checking to `Rearmed#enabled_patches=`
9
+ - Remove support for Rails 3
10
+ - Remove and Extract minitest methods to new gem `minitest-changed-assertions`
11
+ - Remove `ActiveRecord#or` method as it does not always return correct results. Instead use this gem https://github.com/khiav223577/rails_or
12
+ - Remove `ActiveRecord#find_in_relation_batches` and `ActiveRecord#find_relation_each` methods. The reason I implemented these methods was to improve some performance issues I was having. After used this and then later trying some other techniques I can confirm this is a poor technique to improve performance. Therefore I am removing these methods.
4
13
  - **1.0.5 - August 3, 2017**
5
14
  - Fix `options_for_select_include_blank` & `options_for_select_include_blank` for Rails 5.1+ and improved them to patch in safer way
6
15
  - **1.0.4 - July 19, 2017**
data/README.md CHANGED
@@ -1,9 +1,14 @@
1
1
  # Rearmed Rails
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>
2
+
3
+ <a href="https://badge.fury.io/rb/rearmed_rails" target="_blank"><img height="21" style='border:0px;height:21px;' border='0' src="https://badge.fury.io/rb/rearmed_rails.svg" alt="Gem Version"></a>
4
+ <a href='https://travis-ci.org/westonganger/rearmed_rails' target='_blank'><img height='21' style='border:0px;height:21px;' src='https://api.travis-ci.org/westonganger/rearmed_rails.svg?branch=master' border='0' alt='Build Status' /></a>
5
+ <a href='https://rubygems.org/gems/rearmed_rails' target='_blank'><img height='21' style='border:0px;height:21px;' src='https://ruby-gem-downloads-badge.herokuapp.com/rearmed?label=rubygems&type=total&total_label=downloads&color=brightgreen' border='0' alt='RubyGems Downloads' /></a>
6
+ <a href='https://ko-fi.com/A5071NK' target='_blank'><img height='22' style='border:0px;height:22px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=a' border='0' alt='Buy Me a Coffee' /></a>
7
+
3
8
 
4
9
  A collection of helpful methods and monkey patches for Rails
5
10
 
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.
11
+ 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 that you dont know about.
7
12
 
8
13
  ```ruby
9
14
  # Gemfile
@@ -17,73 +22,59 @@ Run `rails g rearmed_rails:setup` to create a settings files in `config/initiali
17
22
  # config/initializers/rearmed.rb
18
23
 
19
24
  RearmedRails.enabled_patches = {
20
- rails: {
21
- active_record: {
22
- find_duplicates: false,
23
- find_in_relation_batches: false,
24
- find_or_create: false,
25
- find_relation_each: false,
26
- newest: false,
27
- or: false,
28
- pluck_to_hash: false,
29
- pluck_to_struct: false,
30
- reset_auto_increment: false,
31
- reset_table: false
32
- },
33
- helpers: {
34
- field_is_array: false,
35
- link_to_confirm: false,
36
- options_for_select_include_blank: false,
37
- options_from_collection_for_select_include_blank: false
38
- },
39
- v3: {
40
- all: false,
41
- pluck: false,
42
- update_columns: false
43
- }
25
+ find_duplicates: false,
26
+ find_or_create: false,
27
+ newest: false,
28
+ pluck_to_hash: false,
29
+ pluck_to_struct: false,
30
+ reset_auto_increment: false,
31
+ reset_table: false
44
32
  },
45
- minitest: {
46
- assert_changed: false,
47
- assert_not_changed: false
33
+ helpers: {
34
+ field_is_array: false,
35
+ link_to_confirm: false,
36
+ options_for_select_include_blank: false,
37
+ options_from_collection_for_select_include_blank: false
48
38
  }
49
39
  }
50
40
 
41
+ RearmedRails.apply_patches!
42
+ ```
43
+
44
+ Some other argument formats the `enabled_patches` option accepts are:
45
+
46
+ ```ruby
47
+ ### Enable everything
48
+ Rearmed.enabled_patches = :all
49
+
50
+ ### Disable everything
51
+ Rearmed.enabled_patches = nil
51
52
 
52
- require 'rearmed_rails/apply_patches'
53
+ ### Hash values can be boolean/nil values also
54
+ Rearmed.enabled_patches = {
55
+ active_record: true,
56
+ helpers: false,
57
+ }
53
58
  ```
54
59
 
60
+ By design, once `apply_patches!` is called then `RearmedRails.enabled_patches` is no longer editable and `apply_patches!` cannot be called again. If you try to do so, it will raise a `PatchesAlreadyAppliedError`. There is no-built in way of changing the patches, if you need to do so (which you shouldn't) that is up to you to figure out.
61
+
55
62
 
56
63
  ## Rails
57
64
 
58
65
  ### ActiveRecord
59
66
 
60
67
  ```ruby
61
- # This version of `or` behaves way nicer than the stupid one that was implemented in Rails 5
62
- # it allows you to do what you need when you want to. This patch is for Rails 4, 5+
63
- Post.where(name: 'foo').or.where(content: 'bar')
64
- Post.where(name: 'foo').or.my_custom_scope
65
- Post.where(name: 'foo').or(Post.where(content: 'bar'))
66
- Post.where(name: 'foo').or(content: 'bar')
67
-
68
- Post.pluck_to_hash(:name, :category, :id)
69
- Post.pluck_to_struct(:name, :category, :id)
70
-
71
68
  Post.find_or_create(name: 'foo', content: 'bar') # use this instead of the super confusing first_or_create method
72
69
  Post.find_or_create!(name: 'foo', content: 'bar')
73
70
 
74
- Post.find_duplicates # return active record relation of all records that have duplicates. By default it skips the primary_key, created_at, updated_at, & deleted_at columns
75
- Post.find_duplicates(:name) # find duplicates based on the name attribute
76
- Post.find_duplicates(:name, :category) # find duplicates based on the name & category attribute
77
- Post.find_duplicates(self.column_names.reject{|x| ['id','created_at','updated_at','deleted_at'].include?(x)})
78
-
79
- # It also can delete duplicates. Valid values for keep are :first & :last. Valid values for delete_method are :destroy & :delete. soft_delete is only used if you are using acts_as_paranoid on your model.
80
- Post.find_duplicates(:name, :category, delete: true)
81
- Post.find_duplicates(:name, :category, delete: {keep: :first, delete_method: :destroy, soft_delete: true}) # these are the default settings for delete: true
82
-
83
71
  Post.newest # get the newest post, by default ordered by :created_at
84
72
  Post.newest(:updated_at) # different sort order
85
73
  Post.newest(:published_at, :created_at) # multiple columns to sort on
86
74
 
75
+ Post.pluck_to_hash(:name, :category, :id)
76
+ Post.pluck_to_struct(:name, :category, :id)
77
+
87
78
  Post.reset_table # delete all records from table and reset autoincrement column (id), works with mysql/mariadb/postgresql/sqlite
88
79
  # or with options
89
80
  Post.reset_table(delete_method: :destroy) # to ensure all callbacks are fired
@@ -92,11 +83,17 @@ Post.reset_auto_increment # reset mysql/mariadb/postgresql/sqlite auto-increment
92
83
  # or with options
93
84
  Post.reset_auto_increment(value: 1, column: :id) # column option is only relevant for postgresql
94
85
 
95
- Post.find_in_relation_batches # this returns a relation instead of an array
96
- Post.find_relation_each # this returns a relation instead of an array
97
- ```
86
+ Post.find_duplicates # return active record relation of all records that have duplicates. By default it skips the primary_key, created_at, updated_at, & deleted_at columns
87
+ Post.find_duplicates(:name) # find duplicates based on the name attribute
88
+ Post.find_duplicates(:name, :category) # find duplicates based on the name & category attribute
89
+ Post.find_duplicates(self.column_names.reject{|x| ['id','created_at','updated_at','deleted_at'].include?(x)})
98
90
 
99
- Note: All methods which involve deletion are compatible with Paranoia & ActsAsParanoid
91
+ # It also can delete duplicates.
92
+ # Valid values for keep are :first & :last.
93
+ # Valid values for delete_method are :destroy & :delete. The soft-delete option is only used if you are using acts_as_paranoid on your model.
94
+ Post.find_duplicates(:name, :category, delete: true)
95
+ Post.find_duplicates(:name, :category, delete: {keep: :first, delete_method: :destroy, soft_delete: true}) # these are the default settings for delete: true
96
+ ```
100
97
 
101
98
  ### Helpers
102
99
 
@@ -110,42 +107,20 @@ options_for_select(@users.map{|x| [x.name, x.id]}, include_blank: true, selected
110
107
  # options_from_collection_for_select_include_blank
111
108
  options_from_collection_for_select(@users, 'id', 'name', include_blank: true, selected: params[:user_id])
112
109
 
113
- # returns to rails 3 behaviour of allowing confirm attribute as well as data-confirm
110
+ # returns Rails v3 behaviour of allowing confirm attribute as well as data-confirm
114
111
  = link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?"
115
112
  ```
116
113
 
117
- ### Rails 3.x Backports
118
- ```ruby
119
- Post.all # Now returns AR relation
120
- Post.first.update_columns(a: 'foo', b: 'bar')
121
- Post.pluck(:name, :id) # adds multi column pluck support ex. => [['first', 1], ['second', 2], ['third', 3]]
122
- ```
123
-
124
- ### Minitest Methods
125
- ```ruby
126
- assert_changed 'user.name' do
127
- user.name = "Bob"
128
- end
129
-
130
- assert_not_changed -> { user.name } do
131
- user.update(user_params)
132
- end
133
-
134
- assert_not_changed lambda{ user.name } do
135
- user.update(user_params)
136
- end
137
- ```
138
-
139
114
  # Contributing
140
115
  If you want to request a new method please raise an issue and we will discuss the idea.
141
116
 
142
117
 
143
118
  # Credits
144
- Created by Weston Ganger - [@westonganger](https://github.com/westonganger)
119
+ Created by [Weston Ganger](https://westonganger.com) - [@westonganger](https://github.com/westonganger)
145
120
 
146
121
  For any consulting or contract work please contact me via my company website: [Solid Foundation Web Development](https://solidfoundationwebdev.com)
147
122
 
148
- ## Similar Libraries Created By Me
123
+ ## Other Libraries in the Rearmed family of Plugins
149
124
  - [Rearmed Ruby](https://github.com/westonganger/rearmed-rb)
150
125
  - [Rearmed JS](https://github.com/westonganger/rearmed_rails)
151
126
  - [Rearmed CSS](https://github.com/westonganger/rearmed_css)
data/Rakefile CHANGED
@@ -5,20 +5,19 @@ task :test do
5
5
  require 'rake/testtask'
6
6
  Rake::TestTask.new do |t|
7
7
  t.libs << 'test'
8
- t.test_files = FileList['test/**/tc_*.rb']
8
+ t.test_files = FileList['test/**/*_test.rb']
9
9
  t.verbose = true
10
10
  end
11
11
  end
12
12
 
13
13
  task :console do
14
- require 'rearmed_rails'
14
+ require 'active_record'
15
+ require 'action_view'
15
16
 
16
- RearmedRails.enabled_patches = {
17
- rails: true,
18
- minitest: true
19
- }
17
+ require 'rearmed_rails'
20
18
 
21
- require 'rearmed_rails/apply_patches'
19
+ RearmedRails.enabled_patches = :all
20
+ RearmedRails.apply_patches!
22
21
 
23
22
  require 'irb'
24
23
  binding.irb
@@ -7,7 +7,7 @@ module RearmedRails
7
7
  create_file "config/initializers/rearmed_rails.rb", <<eos
8
8
  RearmedRails.enabled_patches = #{File.read(File.join(File.dirname(__FILE__), '../../rearmed_rails/default_enabled_patches.hash'))}
9
9
 
10
- require 'rearmed_rails/apply_patches'
10
+ RearmedRails.apply_patches!'
11
11
  eos
12
12
  end
13
13
 
data/lib/rearmed_rails.rb CHANGED
@@ -2,19 +2,58 @@ require 'rearmed_rails/version'
2
2
 
3
3
  module RearmedRails
4
4
 
5
- @enabled_patches = eval(File.read(File.join(File.dirname(__FILE__), 'rearmed_rails/default_enabled_patches.hash')))
5
+ DEFAULT_PATCHES = eval(File.read(File.join(File.dirname(__FILE__), 'rearmed_rails/default_enabled_patches.hash'))).freeze
6
+ private_constant :DEFAULT_PATCHES
7
+
8
+ @enabled_patches = Marshal.load(Marshal.dump(DEFAULT_PATCHES))
9
+ @applied = false
6
10
 
7
11
  def self.enabled_patches=(val)
8
- @enabled_patches = val
12
+ if @applied
13
+ raise ::RearmedRails::Exceptions::PatchesAlreadyAppliedError.new
14
+ else
15
+ if val.nil?
16
+ @enabled_patches = Marshal.load(Marshal.dump(DEFAULT_PATCHES))
17
+ elsif val == :all
18
+ @enabled_patches = val
19
+ elsif val.is_a?(Hash)
20
+ @enabled_patches = Marshal.load(Marshal.dump(DEFAULT_PATCHES))
21
+
22
+ DEFAULT_PATCHES.keys.each do |k|
23
+ methods = val[k] || val[k.to_sym]
24
+ if methods
25
+ if methods.is_a?(Hash) || methods == true
26
+ @enabled_patches[k] = methods
27
+ else
28
+ raise TypeError.new('Invalid value within the hash passed to Rearmed.enabled_patches=')
29
+ end
30
+ end
31
+ end
32
+ else
33
+ raise TypeError.new('Invalid value passed to Rearmed.enabled_patches=')
34
+ end
35
+ end
9
36
  end
10
37
 
11
38
  def self.enabled_patches
12
39
  @enabled_patches
13
40
  end
14
41
 
42
+ def self.apply_patches!
43
+ if @applied
44
+ raise ::RearmedRails::Exceptions::PatchesAlreadyAppliedError.new
45
+ else
46
+ Dir[File.join(__dir__, 'rearmed_rails/monkey_patches/**/*.rb')].each do |filename|
47
+ require filename
48
+ end
49
+
50
+ @applied = true
51
+ end
52
+ end
53
+
15
54
  private
16
55
 
17
- def self.dig(collection, *values)
56
+ def self._dig(collection, *values)
18
57
  current_val = nil
19
58
  current_collection = collection
20
59
  values.each_with_index do |val,i|
@@ -1,31 +1,17 @@
1
1
  {
2
- rails: {
3
- active_record: {
4
- find_duplicates: false,
5
- find_in_relation_batches: false,
6
- find_or_create: false,
7
- find_relation_each: false,
8
- newest: false,
9
- or: false,
10
- pluck_to_hash: false,
11
- pluck_to_struct: false,
12
- reset_auto_increment: false,
13
- reset_table: false
14
- },
15
- helpers: {
16
- field_is_array: false,
17
- link_to_confirm: false,
18
- options_for_select_include_blank: false,
19
- options_from_collection_for_select_include_blank: false
20
- },
21
- v3: {
22
- all: false,
23
- pluck: false,
24
- update_columns: false
25
- },
26
- minitest: {
27
- assert_changed: false,
28
- assert_not_changed: false
29
- }
2
+ active_record: {
3
+ find_duplicates: false,
4
+ find_or_create: false,
5
+ newest: false,
6
+ pluck_to_hash: false,
7
+ pluck_to_struct: false,
8
+ reset_auto_increment: false,
9
+ reset_table: false
10
+ },
11
+ helpers: {
12
+ field_is_array: false,
13
+ link_to_confirm: false,
14
+ options_for_select_include_blank: false,
15
+ options_from_collection_for_select_include_blank: false
30
16
  }
31
17
  }
@@ -0,0 +1,11 @@
1
+ module RearmedRails
2
+ module Exceptions
3
+
4
+ class PatchesAlreadyAppliedError < StandardError
5
+ def initialize
6
+ super("Cannot change or apply patches again after `RearmedRails#apply_patches!` has been called.")
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -1,10 +1,9 @@
1
- enabled = RearmedRails.enabled_patches[:rails] == true
2
- enabled ||= RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record) == true
1
+ enabled = RearmedRails.enabled_patches == :all || RearmedRails._dig(RearmedRails.enabled_patches, :active_record) == true
3
2
 
4
3
  if defined?(ActiveRecord)
5
4
 
6
5
  ActiveRecord::Base.class_eval do
7
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :newest)
6
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :newest)
8
7
  def self.newest(*columns)
9
8
  if columns.empty? || !columns.to_s.include?('created_at')
10
9
  columns << 'created_at'
@@ -18,7 +17,7 @@ if defined?(ActiveRecord)
18
17
  end
19
18
  end
20
19
 
21
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :reset_table)
20
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :reset_table)
22
21
  def self.reset_table(opts={})
23
22
  if opts[:delete_method] && opts[:delete_method].to_sym == :destroy
24
23
  if self.try(:paranoid?)
@@ -53,7 +52,7 @@ if defined?(ActiveRecord)
53
52
  end
54
53
  end
55
54
 
56
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :reset_auto_increment)
55
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :reset_auto_increment)
57
56
  def self.reset_auto_increment(opts={})
58
57
  case self.connection.adapter_name.downcase.to_sym
59
58
  when :mysql2
@@ -69,7 +68,7 @@ if defined?(ActiveRecord)
69
68
  end
70
69
  end
71
70
 
72
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :find_duplicates)
71
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :find_duplicates)
73
72
  def self.find_duplicates(*args)
74
73
  options = {}
75
74
 
@@ -143,7 +142,7 @@ if defined?(ActiveRecord)
143
142
  end
144
143
  end
145
144
 
146
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :find_or_create)
145
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :find_or_create)
147
146
  def self.find_or_create(attrs={}, save_opts={})
148
147
  unless self.where(attrs).limit(1).first
149
148
  x = self.class.new(attrs)
@@ -161,7 +160,7 @@ if defined?(ActiveRecord)
161
160
  end
162
161
  end
163
162
 
164
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :pluck_to_hash)
163
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :pluck_to_hash)
165
164
  def self.pluck_to_hash(*keys)
166
165
  hash_type = keys[-1].is_a?(Hash) ? keys.pop.fetch(:hash_type, HashWithIndifferentAccess) : HashWithIndifferentAccess
167
166
  block_given = block_given?
@@ -175,7 +174,7 @@ if defined?(ActiveRecord)
175
174
  end
176
175
  end
177
176
 
178
- if enabled || enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :pluck_to_struct)
177
+ if enabled || enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :pluck_to_struct)
179
178
  def self.pluck_to_struct(*keys)
180
179
  struct_type = keys[-1].is_a?(Hash) ? keys.pop.fetch(:struct_type, Struct) : Struct
181
180
  block_given = block_given?
@@ -192,7 +191,7 @@ if defined?(ActiveRecord)
192
191
 
193
192
  private
194
193
 
195
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :pluck_to_hash) || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :pluck_to_struct)
194
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :active_record, :pluck_to_hash) || RearmedRails._dig(RearmedRails.enabled_patches, :pluck_to_struct)
196
195
  def self.format_keys(keys)
197
196
  if keys.blank?
198
197
  [column_names, column_names]
@@ -1,9 +1,8 @@
1
- enabled = RearmedRails.enabled_patches[:rails] == true
2
- enabled ||= RearmedRails.dig(RearmedRails.enabled_patches, :rails, :helpers) == true
1
+ enabled = RearmedRails.enabled_patches == :all || RearmedRails._dig(RearmedRails.enabled_patches, :helpers) == true
3
2
 
4
3
  if defined?(ActionView::Helpers)
5
4
 
6
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :helpers, :link_to_confirm)
5
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :helpers, :link_to_confirm)
7
6
  ActionView::Helpers::UrlHelper.module_eval do
8
7
  def convert_options_to_data_attributes(options, html_options)
9
8
  if html_options
@@ -25,7 +24,7 @@ if defined?(ActionView::Helpers)
25
24
  end
26
25
  end
27
26
 
28
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :helpers, :field_is_array)
27
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :helpers, :field_is_array)
29
28
  module ActionView
30
29
  module Helpers
31
30
  module Tags
@@ -53,7 +52,7 @@ if defined?(ActionView::Helpers)
53
52
 
54
53
  RearmedRails::RailsHelpers.module_eval do
55
54
 
56
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :helpers, :options_for_select_include_blank)
55
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :helpers, :options_for_select_include_blank)
57
56
  def options_for_select(container, selected = nil)
58
57
  if selected.is_a?(Hash)
59
58
  include_blank = selected[:include_blank] || selected['include_blank']
@@ -77,7 +76,7 @@ if defined?(ActionView::Helpers)
77
76
  end
78
77
  end
79
78
 
80
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :helpers, :options_for_select_include_blank)
79
+ if enabled || RearmedRails._dig(RearmedRails.enabled_patches, :helpers, :options_for_select_include_blank)
81
80
  def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
82
81
  options = collection.map do |element|
83
82
  [value_for_collection(element, text_method), value_for_collection(element, value_method), option_html_attributes(element)]
@@ -1,3 +1,3 @@
1
1
  module RearmedRails
2
- VERSION = "1.0.5"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -5,53 +5,49 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  require 'yaml'
7
7
  require 'minitest'
8
+ require 'minitest/autorun'
8
9
 
10
+ require 'active_record'
11
+ require 'action_view'
9
12
  require 'rearmed_rails'
10
13
 
11
- require 'minitest/autorun'
14
+ RearmedRails.enabled_patches = :all
15
+ RearmedRails.apply_patches!
12
16
 
13
- class TestRearmedRails < MiniTest::Test
17
+ class RearmedRailsTest < MiniTest::Test
14
18
  def setup
15
- Minitest::Assertions.module_eval do
16
- alias_method :eql, :assert_equal
17
- end
19
+ end
18
20
 
19
- RearmedRails.enabled_patches = {
20
- rails: true,
21
- minitest: true
22
- }
23
- require 'rearmed_rails/apply_patches'
21
+ def teardown
24
22
  end
25
23
 
26
- def test_minitest
27
- str = 'first'
28
- assert_changed "str" do
29
- str = 'second'
30
- end
24
+ def test_enabled_patches
25
+ RearmedRails.instance_variable_set(:@applied, false)
31
26
 
32
- str = 'first'
33
- assert_changed ->{ str } do
34
- str = 'second'
35
- end
27
+ default = RearmedRails.const_get(:DEFAULT_PATCHES)
36
28
 
37
- name = 'first'
38
- assert_changed lambda{ name } do
39
- name = 'second'
40
- end
29
+ RearmedRails.enabled_patches = nil
30
+ assert_equal RearmedRails.enabled_patches, default
41
31
 
42
- name = 'first'
43
- assert_not_changed 'name' do
44
- name = 'first'
45
- end
32
+ RearmedRails.enabled_patches = {}
33
+ assert_equal RearmedRails.enabled_patches, default
46
34
 
47
- name = 'first'
48
- assert_not_changed ->{ name } do
49
- name = 'first'
50
- end
35
+ RearmedRails.enabled_patches = :all
36
+ assert_equal RearmedRails.enabled_patches, :all
37
+
38
+ RearmedRails.enabled_patches = {active_record: true, helpers: false, foo: :bar}
39
+ assert_equal RearmedRails.enabled_patches, default.merge({active_record: true})
51
40
 
52
- name = 'first'
53
- assert_not_changed lambda{ name } do
54
- name = 'first'
41
+ [true, false, [], '', 1, :foo, RearmedRails].each do |x|
42
+ assert_raises TypeError do
43
+ RearmedRails.enabled_patches = x
44
+ end
45
+
46
+ if x != true && x != false
47
+ assert_raises TypeError do
48
+ RearmedRails.enabled_patches = {active_record: x}
49
+ end
50
+ end
55
51
  end
56
52
  end
57
53
 
@@ -74,26 +70,11 @@ class TestRearmedRails < MiniTest::Test
74
70
  #Post.reset_auto_increment # reset mysql/mariadb/postgresql/sqlite auto-increment column, if contains records then defaults to starting from next available number
75
71
  ## or with options
76
72
  #Post.reset_auto_increment(value: 1, column: :id) # column option is only relevant for postgresql
77
-
78
- #Post.find_in_relation_batches # this returns a relation instead of an array
79
- #Post.find_relation_each # this returns a relation instead of an array
80
- end
81
-
82
- def test_rails_3
83
- #my_hash.compact
84
- #my_hash.compact!
85
- #Post.all # Now returns AR relation
86
- #Post.first.update_columns(a: 'foo', b: 'bar')
87
- #Post.pluck(:name, :id) # adds multi column pluck support ex. => [['first', 1], ['second', 2], ['third', 3]]
88
73
  end
89
74
 
90
75
  def test_rails_4
91
- #Post.where(name: 'foo').or.where(content: 'bar')
92
- #Post.where(name: 'foo').or.my_custom_scope
93
- #Post.where(name: 'foo').or(Post.where(content: 'bar'))
94
- #Post.where(name: 'foo).or(content: 'bar')
95
-
96
76
  #= link_to 'Delete', post_path(post), method: :delete, confirm: "Are you sure you want to delete this post?"
97
77
  # returns to rails 3 behaviour of allowing confirm attribute as well as data-confirm
98
78
  end
79
+
99
80
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rearmed_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 2.0.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: 2017-08-04 00:00:00.000000000 Z
11
+ date: 2018-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: A collection of helpful methods and monkey patches for Rails
56
- email: westonganger@gmail.com
56
+ email: weston@westonganger.com
57
57
  executables: []
58
58
  extensions: []
59
59
  extra_rdoc_files: []
@@ -64,16 +64,12 @@ files:
64
64
  - Rakefile
65
65
  - lib/generators/rearmed_rails/setup_generator.rb
66
66
  - lib/rearmed_rails.rb
67
- - lib/rearmed_rails/apply_patches.rb
68
67
  - lib/rearmed_rails/default_enabled_patches.hash
69
- - lib/rearmed_rails/monkey_patches/minitest.rb
70
- - lib/rearmed_rails/monkey_patches/rails/active_record/base.rb
71
- - lib/rearmed_rails/monkey_patches/rails/active_record/batches.rb
72
- - lib/rearmed_rails/monkey_patches/rails/active_record/query_methods.rb
73
- - lib/rearmed_rails/monkey_patches/rails/helpers.rb
74
- - lib/rearmed_rails/monkey_patches/rails/v3.rb
68
+ - lib/rearmed_rails/exceptions.rb
69
+ - lib/rearmed_rails/monkey_patches/active_record.rb
70
+ - lib/rearmed_rails/monkey_patches/helpers.rb
75
71
  - lib/rearmed_rails/version.rb
76
- - test/tc_rearmed.rb
72
+ - test/rearmed_rails_test.rb
77
73
  homepage: https://github.com/westonganger/rearmed_rails
78
74
  licenses: []
79
75
  metadata: {}
@@ -93,9 +89,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
89
  version: '0'
94
90
  requirements: []
95
91
  rubyforge_project:
96
- rubygems_version: 2.6.8
92
+ rubygems_version: 2.7.6
97
93
  signing_key:
98
94
  specification_version: 4
99
95
  summary: A collection of helpful methods and monkey patches for Rails
100
96
  test_files:
101
- - test/tc_rearmed.rb
97
+ - test/rearmed_rails_test.rb
@@ -1,6 +0,0 @@
1
- require 'rearmed_rails/monkey_patches/rails/active_record/base'
2
- require 'rearmed_rails/monkey_patches/rails/active_record/batches'
3
- require 'rearmed_rails/monkey_patches/rails/active_record/query_methods'
4
- require 'rearmed_rails/monkey_patches/rails/helpers'
5
- require 'rearmed_rails/monkey_patches/rails/v3'
6
- require 'rearmed_rails/monkey_patches/minitest'
@@ -1,35 +0,0 @@
1
- if defined?(Minitest::Assertions)
2
-
3
- enabled = RearmedRails.enabled_patches[:minitest] == true
4
-
5
- Minitest::Assertions.module_eval do
6
-
7
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :minitest, :assert_changed)
8
- def assert_changed(expression, &block)
9
- if expression.respond_to?(:call)
10
- e = expression
11
- else
12
- e = lambda{ block.binding.eval(expression) }
13
- end
14
- old = e.call
15
- block.call
16
- refute_equal old, e.call
17
- end
18
- end
19
-
20
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :minitest, :assert_not_changed)
21
- def assert_not_changed(expression, &block)
22
- if expression.respond_to?(:call)
23
- e = expression
24
- else
25
- e = lambda{ block.binding.eval(expression) }
26
- end
27
- old = e.call
28
- block.call
29
- assert_equal old, e.call
30
- end
31
- end
32
-
33
- end
34
-
35
- end
@@ -1,60 +0,0 @@
1
- enabled = RearmedRails.enabled_patches[:rails] == true
2
- enabled ||= RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record) == true
3
-
4
- if defined?(ActiveRecord::Batches)
5
-
6
- ActiveRecord::Batches.module_eval do
7
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :find_in_relation_batches)
8
- def find_in_relation_batches(options = {})
9
- options.assert_valid_keys(:start, :batch_size)
10
-
11
- relation = self
12
- start = options[:start]
13
- batch_size = options[:batch_size] || 1000
14
-
15
- unless block_given?
16
- return to_enum(:find_in_relation_batches, options) do
17
- total = start ? where(table[primary_key].gteq(start)).size : size
18
- (total - 1).div(batch_size) + 1
19
- end
20
- end
21
-
22
- if logger && (arel.orders.present? || arel.taken.present?)
23
- logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size")
24
- end
25
-
26
- relation = relation.reorder(batch_order).limit(batch_size)
27
- #records = start ? relation.where(table[primary_key].gteq(start)).to_a : relation.to_a
28
- records = start ? relation.where(table[primary_key].gteq(start)) : relation
29
-
30
- while records.any?
31
- records_size = records.size
32
- primary_key_offset = records.last.id
33
- raise ActiveRecordError, "Primary key not included in the custom select clause" unless primary_key_offset
34
-
35
- yield records
36
-
37
- break if records_size < batch_size
38
-
39
- records = relation.where(table[primary_key].gt(primary_key_offset))#.to_a
40
- end
41
- end
42
- end
43
-
44
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :find_relation_each)
45
- def find_relation_each(options = {})
46
- if block_given?
47
- find_in_relation_batches(options) do |records|
48
- records.each { |record| yield record }
49
- end
50
- else
51
- enum_for :find_relation_each, options do
52
- options[:start] ? where(table[primary_key].gteq(options[:start])).size : size
53
- end
54
- end
55
- end
56
- end
57
-
58
- end
59
-
60
- end
@@ -1,110 +0,0 @@
1
- enabled = RearmedRails.enabled_patches[:rails] == true
2
- enabled ||= RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record) == true
3
-
4
- if defined?(ActiveRecord)
5
-
6
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :active_record, :or)
7
-
8
- if Rails::VERSION::MAJOR > 4
9
-
10
- unless defined?(ActiveRecord::Relation::QueryMethods)
11
- module ActiveRecord
12
- class Relation
13
- module QueryMethods
14
- end
15
- end
16
- end
17
- end
18
-
19
- module RearmedRails
20
- class OrChain
21
- def initialize(scope)
22
- @scope = scope
23
- end
24
-
25
- def method_missing(method, *args, &block)
26
- other = @scope.klass.unscoped do
27
- @scope.klass.send(method, *args, &block)
28
- end
29
- return @scope.or(other)
30
- end
31
- end
32
- end
33
-
34
- ActiveRecord::QueryMethods.module_eval do
35
- def or(opts=nil, *rest)
36
- if opts.nil?
37
- return RearmedRails::OrChain.new(self)
38
- else
39
- other = opts.is_a?(ActiveRecord::Relation) ? opts : klass.unscoped.where(opts, rest)
40
-
41
- self.where_clause = self.where_clause.or(other.where_clause)
42
- self.having_clause = self.having_clause.or(other.having_clause)
43
-
44
- return self
45
- end
46
- end
47
- end
48
-
49
- else # end of Rails 5+ section, Rails 4 below
50
-
51
- module ActiveRecord
52
- module Querying
53
- delegate :or, to: :all
54
- end
55
-
56
- module QueryMethods
57
- class OrChain
58
- def initialize(scope)
59
- @scope = scope
60
- end
61
-
62
- def method_missing(method, *args, &block)
63
- right_relation = @scope.klass.unscoped do
64
- @scope.klass.send(method, *args, &block)
65
- end
66
- @scope.or(right_relation)
67
- end
68
- end
69
-
70
- def or(opts = :chain, *rest)
71
- if opts == :chain
72
- OrChain.new(self)
73
- else
74
- left = self
75
- right = (ActiveRecord::Relation === opts) ? opts : klass.unscoped.where(opts, rest)
76
-
77
- unless left.where_values.empty? || right.where_values.empty?
78
- left.where_values = [left.where_ast.or(right.where_ast)]
79
- right.where_values = []
80
- end
81
-
82
- left = left.merge(right)
83
- end
84
- end
85
-
86
- private # Returns an Arel AST containing only where_values
87
-
88
- def where_ast
89
- arel_wheres = []
90
-
91
- where_values.each do |where|
92
- arel_wheres << (String === where ? Arel.sql(where) : where)
93
- end
94
-
95
- return Arel::Nodes::Grouping.new(Arel::Nodes::And.new(arel_wheres)) if arel_wheres.length >= 2
96
-
97
- if Arel::Nodes::SqlLiteral === arel_wheres.first
98
- Arel::Nodes::Grouping.new(arel_wheres.first)
99
- else
100
- arel_wheres.first
101
- end
102
- end
103
- end
104
- end
105
-
106
- end # end of Rails 4 section
107
-
108
- end
109
-
110
- end
@@ -1,58 +0,0 @@
1
- enabled = RearmedRails.enabled_patches[:rails] == true
2
- enabled ||= RearmedRails.dig(RearmedRails.enabled_patches, :rails, :v3) == true
3
-
4
- if defined?(ActiveRecord) && ActiveRecord::VERSION::MAJOR < 4
5
-
6
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :v3, :all)
7
- ActiveRecord::FinderMethods.module_eval do
8
- def all(*args)
9
- args.any? ? apply_finder_options(args.first) : self
10
- end
11
- end
12
- end
13
-
14
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :v3, :pluck)
15
- ActiveRecord::Relation.class_eval do
16
- def pluck(*args)
17
- args.map! do |column_name|
18
- if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s)
19
- "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
20
- else
21
- column_name.to_s
22
- end
23
- end
24
-
25
- relation = clone
26
- relation.select_values = args
27
- klass.connection.select_all(relation.arel).map! do |attributes|
28
- initialized_attributes = klass.initialize_attributes(attributes)
29
- attributes.map do |key, attr|
30
- klass.type_cast_attribute(key, initialized_attributes)
31
- end
32
- end
33
- end
34
- end
35
- end
36
-
37
- if enabled || RearmedRails.dig(RearmedRails.enabled_patches, :rails, :v3, :update_columns)
38
- ActiveRecord::Persistence::ClassMethods.module_eval do
39
- def update_columns(attributes)
40
- raise ActiveRecordError, "cannot update a new record" if new_record?
41
- raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
42
-
43
- attributes.each_key do |key|
44
- raise ActiveRecordError, "#{key.to_s} is marked as readonly" if self.class.readonly_attributes.include?(key.to_s)
45
- end
46
-
47
- updated_count = self.class.unscoped.where(self.class.primary_key => id).update_all(attributes)
48
-
49
- attributes.each do |k, v|
50
- raw_write_attribute(k, v)
51
- end
52
-
53
- updated_count == 1
54
- end
55
- end
56
- end
57
-
58
- end