rearmed_rails 1.0.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- 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