ruby-rails-extensions 1.0.0 → 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 +34 -0
- data/lib/ruby-rails-extensions/errors.rb +17 -0
- data/lib/ruby-rails-extensions/extensions/all_keys.rb +10 -0
- data/lib/ruby-rails-extensions/extensions/all_values.rb +10 -0
- data/lib/ruby-rails-extensions/extensions/any_key.rb +10 -0
- data/lib/ruby-rails-extensions/extensions/any_value.rb +10 -0
- data/lib/ruby-rails-extensions/extensions/assign_nil.rb +67 -0
- data/lib/ruby-rails-extensions/extensions/boolean_scope.rb +49 -0
- data/lib/ruby-rails-extensions/extensions/clean_string.rb +41 -0
- data/lib/ruby-rails-extensions/extensions/compact_blank_join.rb +13 -0
- data/lib/ruby-rails-extensions/extensions/find_bang.rb +1 -10
- data/lib/ruby-rails-extensions/extensions/humanize_symbol.rb +11 -0
- data/lib/ruby-rails-extensions/extensions/no_keys.rb +10 -0
- data/lib/ruby-rails-extensions/extensions/no_values.rb +10 -0
- data/lib/ruby-rails-extensions/extensions/only_some.rb +28 -0
- data/lib/ruby-rails-extensions/extensions/presence_bang.rb +1 -10
- data/lib/ruby-rails-extensions/extensions/quarter_dates.rb +47 -0
- data/lib/ruby-rails-extensions/extensions/range_add.rb +47 -0
- data/lib/ruby-rails-extensions/extensions/range_multiply.rb +47 -0
- data/lib/ruby-rails-extensions/extensions/safe_parse.rb +42 -0
- data/lib/ruby-rails-extensions/extensions/select_present.rb +11 -0
- data/lib/ruby-rails-extensions/extensions/select_present_join.rb +7 -0
- data/lib/ruby-rails-extensions/extensions/set_to_sentence.rb +11 -0
- data/lib/ruby-rails-extensions/extensions/to_local.rb +26 -0
- data/lib/ruby-rails-extensions/extensions/to_negative_i.rb +45 -0
- data/lib/ruby-rails-extensions/extensions/to_nonzero_i.rb +45 -0
- data/lib/ruby-rails-extensions/extensions/to_positive_i.rb +45 -0
- data/lib/ruby-rails-extensions/extensions/todays_date.rb +17 -0
- data/lib/ruby-rails-extensions/extensions/uniq_map.rb +25 -0
- data/lib/ruby-rails-extensions/extensions/weighted_sum.rb +25 -0
- data/lib/ruby-rails-extensions/extensions/zero_range.rb +22 -0
- data/lib/ruby-rails-extensions/version.rb +1 -1
- data/lib/ruby-rails-extensions.rb +85 -47
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 066eeb0d0c0c755afd91c41eaf18e9e1446635d8fcc80bf37e4d3b9fd76348dd
|
4
|
+
data.tar.gz: 321af547a582a1059aeea22b1a9582ab9fb6a513eb4c08041b52e96c6ded0586
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bb6a7aab3a148d1c6267e014c782a7c1a227fa0c784ed8b2d52ecd370d025559c0a7aba414ad4b8a1b19256ea661bc647177203b8263a0a254cc4fe189b9f12
|
7
|
+
data.tar.gz: 6d3574d41a547413f41ce0b397646a7b2002a0585ba77d24eb5f4bada7d719c78c49be78348529b4a42cd6014d2a065dd1cc1c396ab45815c5c3e55f34ec2785
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,40 @@
|
|
1
1
|
Unreleased Changes
|
2
2
|
------------------
|
3
3
|
|
4
|
+
1.1.0 (2023-09-27)
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* Modules added:
|
8
|
+
* `safe_parse`
|
9
|
+
* `to_local`
|
10
|
+
* `assign_nil`
|
11
|
+
* `todays_date`
|
12
|
+
* `humanize_symbol`
|
13
|
+
* `weighted_sum`
|
14
|
+
* `any_value`
|
15
|
+
* `all_values`
|
16
|
+
* `no_values`
|
17
|
+
* `any_key`
|
18
|
+
* `all_keys`
|
19
|
+
* `no_keys`
|
20
|
+
* `set_to_sentence`
|
21
|
+
* `uniq_map`
|
22
|
+
* `only_some`
|
23
|
+
* `clean_string`
|
24
|
+
* `select_present`
|
25
|
+
* `quarter_dates`
|
26
|
+
* `compact_blank_join`
|
27
|
+
* `select_present_join`
|
28
|
+
* `range_add`
|
29
|
+
* `range_multiply`
|
30
|
+
* `zero_range`
|
31
|
+
* `boolean_scope`
|
32
|
+
* `to_positive_i`
|
33
|
+
* `to_negative_i`
|
34
|
+
* `to_nonzero_i`
|
35
|
+
* Other changes:
|
36
|
+
* Restructured errors' namespace
|
37
|
+
|
4
38
|
1.0.0 (2023-09-25)
|
5
39
|
------------------
|
6
40
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyRailsExtensions
|
4
|
+
module Errors
|
5
|
+
class NonNumericError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class NotFoundError < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
class BlankObjectError < StandardError
|
12
|
+
end
|
13
|
+
|
14
|
+
class InvalidFormatError < StandardError
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if defined?(ActiveModel::AttributeAssignment) && Hash.method_defined?(:stringify_keys)
|
4
|
+
module ActiveModel
|
5
|
+
module AttributeAssignment
|
6
|
+
unless method_defined?(:assign_nil_attributes)
|
7
|
+
# Allows you to set nil attributes by passing in a hash of attributes with
|
8
|
+
# keys matching the attribute names.
|
9
|
+
#
|
10
|
+
# @raise [ActiveModel::ForbiddenAttributesError] If the passed hash responds to `permitted?` method
|
11
|
+
# and the return value of this method is +false+.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
#
|
15
|
+
# class Cat
|
16
|
+
# include ActiveModel::AttributeAssignment
|
17
|
+
# attr_accessor :name, :status
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# cat = Cat.new
|
21
|
+
# cat.assign_nil_attributes(name: "Gorby")
|
22
|
+
# cat.name # => 'Gorby'
|
23
|
+
# cat.status # => nil
|
24
|
+
# cat.assign_nil_attributes(status: "yawning")
|
25
|
+
# cat.name # => 'Gorby'
|
26
|
+
# cat.status # => 'yawning'
|
27
|
+
# cat.assign_nil_attributes(status: "sleeping")
|
28
|
+
# cat.name # => 'Gorby'
|
29
|
+
# cat.status # => 'yawning'
|
30
|
+
#
|
31
|
+
# @param new_attributes
|
32
|
+
#
|
33
|
+
# @return [void]
|
34
|
+
#
|
35
|
+
def assign_nil_attributes(new_attributes)
|
36
|
+
unless new_attributes.respond_to?(:stringify_keys)
|
37
|
+
raise(ArgumentError, 'When assigning attributes, you must pass a hash as an argument.')
|
38
|
+
end
|
39
|
+
|
40
|
+
return if new_attributes.empty?
|
41
|
+
|
42
|
+
attributes = new_attributes.stringify_keys
|
43
|
+
|
44
|
+
_assign_nil_attributes(sanitize_for_mass_assignment(attributes))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
unless private_method_defined?(:_assign_nil_attributes)
|
51
|
+
# Assign any `nil` attribute
|
52
|
+
#
|
53
|
+
# @param attributes [Hash]
|
54
|
+
#
|
55
|
+
# @return [void]
|
56
|
+
#
|
57
|
+
def _assign_nil_attributes(attributes)
|
58
|
+
attributes.each do |k, v|
|
59
|
+
next unless v.nil?
|
60
|
+
|
61
|
+
_assign_attribute(k, v)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyRailsExtensions
|
4
|
+
module Extensions
|
5
|
+
module BooleanScope
|
6
|
+
if defined?(ActiveSupport::Concern)
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
# Calls `boolean_scope` for each boolean column
|
11
|
+
def add_boolean_scopes
|
12
|
+
return unless table_exists?
|
13
|
+
|
14
|
+
columns.each do |column|
|
15
|
+
next unless column.type == :boolean
|
16
|
+
|
17
|
+
# @!method not_#{column.name}?
|
18
|
+
# @return [Boolean]
|
19
|
+
# @!method column.name
|
20
|
+
# @!scope class
|
21
|
+
# @return [ActiveRecord::Relation<>]
|
22
|
+
# @!method not_#{column.name}
|
23
|
+
# @!scope class
|
24
|
+
# @return [ActiveRecord::Relation<>]
|
25
|
+
boolean_scope(column.name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Defines 2 scopes and 1 ? method
|
30
|
+
#
|
31
|
+
# @param column_name [Symbol, String] The boolean column name
|
32
|
+
# @param negative [Symbol, String] opposite of the column name
|
33
|
+
# defaults to the column name with "not_" as a prefix
|
34
|
+
#
|
35
|
+
# @return [void]
|
36
|
+
#
|
37
|
+
def boolean_scope(column_name, negative = "not_#{column_name}")
|
38
|
+
scope(:"#{column_name}", -> { where(column_name => true) })
|
39
|
+
scope(:"#{negative}", -> { where(column_name => false) })
|
40
|
+
|
41
|
+
define_method("#{negative}?") do
|
42
|
+
!__send__("#{column_name}?")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
String.class_eval do
|
4
|
+
unless method_defined?(:clean!)
|
5
|
+
# Remove all non-UTF-8 chars from a string.
|
6
|
+
#
|
7
|
+
# @param replace_with [String, nil] What to replace invalid chars with.
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def clean!(replace_with = '')
|
12
|
+
replace(encode('UTF-8', invalid: :replace, undef: :replace, replace: replace_with))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
unless method_defined?(:clean)
|
17
|
+
# @see {#clean!}
|
18
|
+
def clean(replace_with = '')
|
19
|
+
dup.clean!(replace_with)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
unless method_defined?(:clean_binary!)
|
24
|
+
# Remove all non-UTF-8 chars from a string and convert to binary.
|
25
|
+
#
|
26
|
+
# @param replace_with [String, nil] What to replace invalid chars with.
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
def clean_binary!(replace_with = '')
|
31
|
+
replace(encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: replace_with))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
unless method_defined?(:clean_binary)
|
36
|
+
# @see {#clean_binary!}
|
37
|
+
def clean_binary(replace_with = '')
|
38
|
+
dup.clean_binary!(replace_with)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Enumerable.class_eval do
|
4
|
+
if method_defined?(:compact_blank) && !method_defined?(:compact_blank_join)
|
5
|
+
# Joins the elements together after calling `compact_blank`
|
6
|
+
#
|
7
|
+
# @return [String]
|
8
|
+
#
|
9
|
+
def compact_blank_join(using = '')
|
10
|
+
compact_blank.join(using)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -3,21 +3,12 @@
|
|
3
3
|
require 'forwardable'
|
4
4
|
require 'set'
|
5
5
|
|
6
|
-
module RubyRailsExtensions
|
7
|
-
module Extensions
|
8
|
-
module FindBang
|
9
|
-
class NotFoundError < StandardError
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
6
|
Array.class_eval do
|
16
7
|
unless method_defined?(:find!)
|
17
8
|
# :nodoc:
|
18
9
|
def find!(&block)
|
19
10
|
x = find(&block)
|
20
|
-
raise(RubyRailsExtensions::
|
11
|
+
raise(RubyRailsExtensions::Errors::NotFoundError, 'Not found') if x.nil?
|
21
12
|
|
22
13
|
x
|
23
14
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Array.class_eval do
|
4
|
+
unless method_defined?(:only_some?)
|
5
|
+
# Same as `my_array.any?(&block) && !my_array.all?(&block)`
|
6
|
+
#
|
7
|
+
# @return [Boolean]
|
8
|
+
#
|
9
|
+
def only_some?(*meth_args)
|
10
|
+
# Check arg size since `any?` arg take presence over block
|
11
|
+
return any?(*meth_args) && !all?(*meth_args) if meth_args.size.positive?
|
12
|
+
|
13
|
+
any = false
|
14
|
+
all = true
|
15
|
+
|
16
|
+
each do |*args|
|
17
|
+
result = yield(*args)
|
18
|
+
|
19
|
+
any ||= result
|
20
|
+
all &&= result
|
21
|
+
|
22
|
+
break if any && !all
|
23
|
+
end
|
24
|
+
|
25
|
+
return any && !all
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,14 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module RubyRailsExtensions
|
4
|
-
module Extensions
|
5
|
-
module PresenceBang
|
6
|
-
class BlankObjectError < StandardError
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
3
|
Object.class_eval do
|
13
4
|
unless method_defined?(:presence!)
|
14
5
|
# Returns self if `present?`
|
@@ -18,7 +9,7 @@ Object.class_eval do
|
|
18
9
|
# @return [*]
|
19
10
|
#
|
20
11
|
def presence!
|
21
|
-
raise(RubyRailsExtensions::
|
12
|
+
raise(RubyRailsExtensions::Errors::BlankObjectError, 'Blank object') if blank?
|
22
13
|
|
23
14
|
self
|
24
15
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
String.class_eval do
|
4
|
+
if !method_defined?(:quarter_start) && Date.instance_methods.include?(:beginning_of_quarter)
|
5
|
+
# Return the quarter start date.
|
6
|
+
#
|
7
|
+
# @return [Date]
|
8
|
+
#
|
9
|
+
def quarter_start
|
10
|
+
quarter_date.beginning_of_quarter
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if !method_defined?(:quarter_end) && Date.instance_methods.include?(:end_of_quarter)
|
15
|
+
# Return the quarter end date.
|
16
|
+
#
|
17
|
+
# @return [Date]
|
18
|
+
#
|
19
|
+
def quarter_end
|
20
|
+
quarter_date.end_of_quarter
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
unless private_method_defined?(:quarter_date)
|
27
|
+
# Parses a string for a quarter date. Expects the string to follow: 'qQyy' where
|
28
|
+
# q = 1/2/3/4 and yy to be the last two digits of the year.
|
29
|
+
#
|
30
|
+
# @raise [RubyRailsExtensions::Errors::InvalidFormatError] if `self` is not qQyy
|
31
|
+
#
|
32
|
+
# @return [Date]
|
33
|
+
#
|
34
|
+
def quarter_date
|
35
|
+
unless match?(/\A[1-4]q\d\d\z/i)
|
36
|
+
raise(RubyRailsExtensions::Errors::InvalidFormatError, "Unexpected format (given #{self}, expected qQyy)")
|
37
|
+
end
|
38
|
+
|
39
|
+
values = scan(/\d/)
|
40
|
+
quarter = values.shift.to_i
|
41
|
+
year = "20#{values.join('')}".to_i
|
42
|
+
month = quarter * 3
|
43
|
+
|
44
|
+
Date.new(year, month, 1)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Range.class_eval do
|
4
|
+
unless method_defined?(:+)
|
5
|
+
# Allows adding a to a range. This will create a new range since ranges are immutable.
|
6
|
+
#
|
7
|
+
# @note Make sure to assign this to a new var or inline replacement `+=`.
|
8
|
+
#
|
9
|
+
# @raise [RubyRailsExtensions::Errors::NonNumericError]
|
10
|
+
#
|
11
|
+
# @param other [Numeric, Range<Numeric>]
|
12
|
+
#
|
13
|
+
# @return [Range]
|
14
|
+
#
|
15
|
+
def +(other)
|
16
|
+
unless self.begin.is_a?(Numeric)
|
17
|
+
raise(
|
18
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
19
|
+
"Wrong range type (given #{self.begin.class}, expected Numeric)"
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
new_begin, new_end =
|
24
|
+
if other.is_a?(Range)
|
25
|
+
unless other.begin.is_a?(Numeric)
|
26
|
+
raise(
|
27
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
28
|
+
"Wrong range type (given #{other.begin.class}, expected Numeric)"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
[self.begin + other.begin, self.end + other.end]
|
33
|
+
else
|
34
|
+
unless other.is_a?(Numeric)
|
35
|
+
raise(
|
36
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
37
|
+
"Wrong type (given #{other.class}, expected Numeric)"
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
[self.begin + other, self.end + other]
|
42
|
+
end
|
43
|
+
|
44
|
+
Range.new(new_begin, new_end, exclude_end?)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Range.class_eval do
|
4
|
+
unless method_defined?(:*)
|
5
|
+
# Allows multiplying a range. This will create a new range due to range objects being immutable.
|
6
|
+
#
|
7
|
+
# @note Make sure to assign this to a new var or do inline replacement `*=`.
|
8
|
+
#
|
9
|
+
# @raise [RubyRailsExtensions::Errors::NonNumericError]
|
10
|
+
#
|
11
|
+
# @param other [Numeric, Range<Numeric>]
|
12
|
+
#
|
13
|
+
# @return [Range]
|
14
|
+
#
|
15
|
+
def *(other)
|
16
|
+
unless self.begin.is_a?(Numeric)
|
17
|
+
raise(
|
18
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
19
|
+
"Wrong range type (given #{self.begin.class}, expected Numeric)"
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
new_begin, new_end =
|
24
|
+
if other.is_a?(Range)
|
25
|
+
unless other.begin.is_a?(Numeric)
|
26
|
+
raise(
|
27
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
28
|
+
"Wrong range type (given #{other.begin.class}, expected Numeric)"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
[self.begin * other.begin, self.end * other.end]
|
33
|
+
else
|
34
|
+
unless other.is_a?(Numeric)
|
35
|
+
raise(
|
36
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
37
|
+
"Wrong type (given #{other.class}, expected Numeric)"
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
[self.begin * other, self.end * other]
|
42
|
+
end
|
43
|
+
|
44
|
+
Range.new(new_begin, new_end, exclude_end?)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Date.class_eval do
|
4
|
+
class << self
|
5
|
+
unless method_defined?(:safe_parse)
|
6
|
+
# Parses the `str` and returns `nil` if invalid
|
7
|
+
def safe_parse(str)
|
8
|
+
parse(str)
|
9
|
+
rescue
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Time.class_eval do
|
17
|
+
class << self
|
18
|
+
unless method_defined?(:safe_parse)
|
19
|
+
# Parses the `str` and returns `nil` if invalid
|
20
|
+
def safe_parse(str)
|
21
|
+
parse(str)
|
22
|
+
rescue
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if defined?(ActiveSupport::TimeZone)
|
30
|
+
ActiveSupport::TimeZone.class_eval do
|
31
|
+
class << self
|
32
|
+
unless method_defined?(:safe_parse)
|
33
|
+
# Parses the `str` and returns `nil` if invalid
|
34
|
+
def safe_parse(str)
|
35
|
+
parse(str)
|
36
|
+
rescue
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Enumerable.class_eval do
|
4
|
+
if method_defined?(:compact_blank) && !method_defined?(:select_present)
|
5
|
+
alias_method :select_present, :compact_blank
|
6
|
+
end
|
7
|
+
|
8
|
+
if method_defined?(:compact_blank!) && !method_defined?(:select_present!)
|
9
|
+
alias_method :select_present!, :compact_blank!
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# TimeWithZone defines `in_time_zone`
|
4
|
+
if defined?(ActiveSupport::TimeWithZone)
|
5
|
+
require 'forwardable'
|
6
|
+
|
7
|
+
Time.class_eval do
|
8
|
+
unless method_defined?(:to_local)
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :to_datetime, :to_local
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
DateTime.class_eval do
|
16
|
+
unless method_defined?(:to_local)
|
17
|
+
# Converts to an Eastern time zone
|
18
|
+
#
|
19
|
+
# @return [DateTime]
|
20
|
+
#
|
21
|
+
def to_local
|
22
|
+
in_time_zone(RubyRailsExtensions.configuration.default_time_zone || 'Eastern Time (US & Canada)').to_datetime
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
String.class_eval do
|
4
|
+
unless method_defined?(:to_negative_i)
|
5
|
+
# Calls `to_i` and returns the value if it is negative
|
6
|
+
#
|
7
|
+
# @return [Integer, Nil]
|
8
|
+
#
|
9
|
+
def to_negative_i
|
10
|
+
val = to_i
|
11
|
+
|
12
|
+
return unless val.negative?
|
13
|
+
|
14
|
+
val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Numeric.class_eval do
|
20
|
+
unless method_defined?(:to_negative_i)
|
21
|
+
# Calls `to_i` and returns the value if it is negative
|
22
|
+
#
|
23
|
+
# @return [Integer, Nil]
|
24
|
+
#
|
25
|
+
def to_negative_i
|
26
|
+
val = to_i
|
27
|
+
|
28
|
+
return unless val.negative?
|
29
|
+
|
30
|
+
val
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
NilClass.class_eval do
|
36
|
+
unless method_defined?(:to_negative_i)
|
37
|
+
# Calls `to_i` and returns the value if it is negative
|
38
|
+
#
|
39
|
+
# @return [Nil]
|
40
|
+
#
|
41
|
+
def to_negative_i
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
String.class_eval do
|
4
|
+
unless method_defined?(:to_nonzero_i)
|
5
|
+
# Calls `to_i` and returns the value if it is nonzero
|
6
|
+
#
|
7
|
+
# @return [Integer, Nil]
|
8
|
+
#
|
9
|
+
def to_nonzero_i
|
10
|
+
val = to_i
|
11
|
+
|
12
|
+
return if val.zero?
|
13
|
+
|
14
|
+
val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Numeric.class_eval do
|
20
|
+
unless method_defined?(:to_nonzero_i)
|
21
|
+
# Calls `to_i` and returns the value if it is nonzero
|
22
|
+
#
|
23
|
+
# @return [Integer, Nil]
|
24
|
+
#
|
25
|
+
def to_nonzero_i
|
26
|
+
val = to_i
|
27
|
+
|
28
|
+
return if val.zero?
|
29
|
+
|
30
|
+
val
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
NilClass.class_eval do
|
36
|
+
unless method_defined?(:to_nonzero_i)
|
37
|
+
# Calls `to_i` and returns the value if it is nonzero
|
38
|
+
#
|
39
|
+
# @return [Integer, Nil]
|
40
|
+
#
|
41
|
+
def to_nonzero_i
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
String.class_eval do
|
4
|
+
unless method_defined?(:to_positive_i)
|
5
|
+
# Calls `to_i` and returns the value if it is positive
|
6
|
+
#
|
7
|
+
# @return [Integer, Nil]
|
8
|
+
#
|
9
|
+
def to_positive_i
|
10
|
+
val = to_i
|
11
|
+
|
12
|
+
return unless val.positive?
|
13
|
+
|
14
|
+
val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Numeric.class_eval do
|
20
|
+
unless method_defined?(:to_positive_i)
|
21
|
+
# Calls `to_i` and returns the value if it is positive
|
22
|
+
#
|
23
|
+
# @return [Integer, Nil]
|
24
|
+
#
|
25
|
+
def to_positive_i
|
26
|
+
val = to_i
|
27
|
+
|
28
|
+
return unless val.positive?
|
29
|
+
|
30
|
+
val
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
NilClass.class_eval do
|
36
|
+
unless method_defined?(:to_positive_i)
|
37
|
+
# Calls `to_i` and returns the value if it is positive
|
38
|
+
#
|
39
|
+
# @return [Integer, Nil]
|
40
|
+
#
|
41
|
+
def to_positive_i
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if defined?(ActiveSupport::TimeWithZone) && Time.method_defined?(:to_local)
|
4
|
+
Date.class_eval do
|
5
|
+
class << self
|
6
|
+
unless method_defined?(:todays_date)
|
7
|
+
# Returns today according to Eastern time
|
8
|
+
#
|
9
|
+
# @return [Date]
|
10
|
+
#
|
11
|
+
def todays_date
|
12
|
+
Time.zone.now.to_local.to_date
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Array.class_eval do
|
4
|
+
unless method_defined?(:uniq_map)
|
5
|
+
# Same as `my_array.map(&block).uniq`
|
6
|
+
#
|
7
|
+
# @return [Array, Enumerable]
|
8
|
+
#
|
9
|
+
def uniq_map
|
10
|
+
return to_enum(:uniq_map) unless block_given?
|
11
|
+
|
12
|
+
results = []
|
13
|
+
|
14
|
+
each do |*args|
|
15
|
+
result = yield(*args)
|
16
|
+
|
17
|
+
next if results.include?(result)
|
18
|
+
|
19
|
+
results.push(result)
|
20
|
+
end
|
21
|
+
|
22
|
+
return results
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Array.class_eval do
|
4
|
+
unless method_defined?(:weighted_sum)
|
5
|
+
# Sums the array with each element weighing 10 times as the next.
|
6
|
+
# Expects `self` to be [Array<Numeric>]
|
7
|
+
#
|
8
|
+
# @raise [RubyRailsExtensions::Errors::NonNumericError] if any element is not Numeric
|
9
|
+
#
|
10
|
+
# @return [Integer]
|
11
|
+
#
|
12
|
+
def weighted_sum
|
13
|
+
each_with_index.sum do |val, index|
|
14
|
+
unless Numeric === val
|
15
|
+
raise(
|
16
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
17
|
+
"Wrong element type (given #{val.class}, expected Numeric)"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
val * (10**(size - index))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Range.class_eval do
|
4
|
+
unless method_defined?(:zero?)
|
5
|
+
# Checks if the whole range is zero.
|
6
|
+
#
|
7
|
+
# @raise [RubyRailsExtensions::Errors::NonNumericError]
|
8
|
+
#
|
9
|
+
# @return [Boolean]
|
10
|
+
#
|
11
|
+
def zero?
|
12
|
+
unless self.begin.is_a?(Numeric)
|
13
|
+
raise(
|
14
|
+
RubyRailsExtensions::Errors::NonNumericError,
|
15
|
+
"Wrong range type (given #{self.begin.class}, expected Numeric)"
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
self.begin.zero? && self.end.zero?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,40 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# @return [CONFIGURATION]
|
5
|
-
def self.configuration
|
6
|
-
@configuration ||= CONFIGURATION.new
|
7
|
-
end
|
8
|
-
|
9
|
-
# @yield [Configuration]
|
10
|
-
def self.configure
|
11
|
-
yield(configuration)
|
12
|
-
|
13
|
-
gem_list.each do |gem_base|
|
14
|
-
next unless configuration.public_send("#{flag_name(gem_base)}?")
|
15
|
-
|
16
|
-
require_relative("ruby-rails-extensions/extensions/#{gem_base}")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Array<Symbol>]
|
21
|
-
def configuration_flags
|
22
|
-
CONFIGURATION.members
|
23
|
-
end
|
24
|
-
|
25
|
-
module_function :configuration_flags
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
# @return [Symbol] the flag name
|
30
|
-
def flag_name(gem_base)
|
31
|
-
:"include_#{gem_base}"
|
32
|
-
end
|
33
|
-
|
34
|
-
module_function :flag_name
|
3
|
+
require_relative 'ruby-rails-extensions/errors'
|
35
4
|
|
5
|
+
module RubyRailsExtensions
|
6
|
+
class Configuration
|
36
7
|
BOOLEAN_GEMS = %i[
|
8
|
+
all_keys
|
9
|
+
all_values
|
10
|
+
any_key
|
11
|
+
any_value
|
12
|
+
assign_nil
|
13
|
+
boolean_scope
|
14
|
+
clean_string
|
37
15
|
compact_map
|
16
|
+
compact_blank_join
|
38
17
|
current_day
|
39
18
|
current_month
|
40
19
|
current_week
|
@@ -46,46 +25,105 @@ module RubyRailsExtensions
|
|
46
25
|
first_dupe
|
47
26
|
google_format
|
48
27
|
hash_only
|
28
|
+
humanize_symbol
|
49
29
|
in_utc
|
50
30
|
input
|
51
31
|
month_and_year
|
52
32
|
month_year
|
33
|
+
no_keys
|
34
|
+
no_values
|
35
|
+
only_some
|
53
36
|
overlaps
|
54
37
|
pipe
|
55
38
|
presence_bang
|
39
|
+
quarter_dates
|
40
|
+
range_add
|
41
|
+
range_multiply
|
56
42
|
remove_reserved_keywords
|
43
|
+
safe_parse
|
44
|
+
select_present
|
45
|
+
select_present_join
|
46
|
+
set_to_sentence
|
57
47
|
to_bool
|
58
48
|
to_dec
|
59
49
|
to_i
|
50
|
+
to_local
|
51
|
+
to_negative_i
|
52
|
+
to_nonzero_i
|
60
53
|
to_or_sentence
|
54
|
+
to_positive_i
|
61
55
|
to_sort_i
|
62
56
|
to_x
|
57
|
+
todays_date
|
58
|
+
uniq_map
|
63
59
|
usd_to_f
|
64
60
|
usd_to_i
|
61
|
+
weighted_sum
|
65
62
|
yesno
|
63
|
+
zero_range
|
66
64
|
].freeze
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
attr_accessor :default_time_zone
|
67
|
+
|
68
|
+
# @return [Symbol] the flag name
|
69
|
+
def self.flag_name(gem_base)
|
70
|
+
:"include_#{gem_base}"
|
71
71
|
end
|
72
72
|
|
73
|
-
|
73
|
+
BOOLEAN_GEMS.each do |extension_name|
|
74
|
+
include_extension = flag_name(extension_name)
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
76
|
+
attr_accessor include_extension
|
77
|
+
|
78
|
+
define_method(:"#{extension_name}?") do
|
79
|
+
public_send(include_extension) != false
|
80
80
|
end
|
81
|
+
end
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
# Sets all flags to true by default
|
84
|
+
def initialize
|
85
|
+
super
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
BOOLEAN_GEMS.each do |extension_name|
|
88
|
+
include_extension = flag_name(extension_name)
|
89
|
+
|
90
|
+
public_send("#{include_extension}=", true)
|
89
91
|
end
|
90
92
|
end
|
93
|
+
|
94
|
+
# @return [Array<Symbol>]
|
95
|
+
def flags
|
96
|
+
BOOLEAN_GEMS.map { |f| flag_name(f) }
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# @return [Symbol] the flag name
|
102
|
+
def flag_name(gem_base)
|
103
|
+
self.class.flag_name(gem_base)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# @return [Configuration]
|
108
|
+
def self.configuration
|
109
|
+
@configuration ||= Configuration.new
|
110
|
+
end
|
111
|
+
|
112
|
+
# @yield [Configuration]
|
113
|
+
def self.configure
|
114
|
+
yield(configuration)
|
115
|
+
|
116
|
+
Configuration::BOOLEAN_GEMS.each do |extension|
|
117
|
+
next unless configuration.public_send("#{extension}?")
|
118
|
+
|
119
|
+
require_relative("ruby-rails-extensions/extensions/#{extension}")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# @return [Array<Symbol>]
|
124
|
+
def configuration_flags
|
125
|
+
configuration.flags
|
126
|
+
end
|
127
|
+
|
128
|
+
module_function :configuration_flags
|
91
129
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-rails-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brands Insurance
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop-rubomatic-rails
|
@@ -40,6 +40,15 @@ files:
|
|
40
40
|
- CHANGELOG.md
|
41
41
|
- LICENSE.txt
|
42
42
|
- lib/ruby-rails-extensions.rb
|
43
|
+
- lib/ruby-rails-extensions/errors.rb
|
44
|
+
- lib/ruby-rails-extensions/extensions/all_keys.rb
|
45
|
+
- lib/ruby-rails-extensions/extensions/all_values.rb
|
46
|
+
- lib/ruby-rails-extensions/extensions/any_key.rb
|
47
|
+
- lib/ruby-rails-extensions/extensions/any_value.rb
|
48
|
+
- lib/ruby-rails-extensions/extensions/assign_nil.rb
|
49
|
+
- lib/ruby-rails-extensions/extensions/boolean_scope.rb
|
50
|
+
- lib/ruby-rails-extensions/extensions/clean_string.rb
|
51
|
+
- lib/ruby-rails-extensions/extensions/compact_blank_join.rb
|
43
52
|
- lib/ruby-rails-extensions/extensions/compact_map.rb
|
44
53
|
- lib/ruby-rails-extensions/extensions/current_day.rb
|
45
54
|
- lib/ruby-rails-extensions/extensions/current_month.rb
|
@@ -52,23 +61,42 @@ files:
|
|
52
61
|
- lib/ruby-rails-extensions/extensions/first_dupe.rb
|
53
62
|
- lib/ruby-rails-extensions/extensions/google_format.rb
|
54
63
|
- lib/ruby-rails-extensions/extensions/hash_only.rb
|
64
|
+
- lib/ruby-rails-extensions/extensions/humanize_symbol.rb
|
55
65
|
- lib/ruby-rails-extensions/extensions/in_utc.rb
|
56
66
|
- lib/ruby-rails-extensions/extensions/input.rb
|
57
67
|
- lib/ruby-rails-extensions/extensions/month_and_year.rb
|
58
68
|
- lib/ruby-rails-extensions/extensions/month_year.rb
|
69
|
+
- lib/ruby-rails-extensions/extensions/no_keys.rb
|
70
|
+
- lib/ruby-rails-extensions/extensions/no_values.rb
|
71
|
+
- lib/ruby-rails-extensions/extensions/only_some.rb
|
59
72
|
- lib/ruby-rails-extensions/extensions/overlaps.rb
|
60
73
|
- lib/ruby-rails-extensions/extensions/pipe.rb
|
61
74
|
- lib/ruby-rails-extensions/extensions/presence_bang.rb
|
75
|
+
- lib/ruby-rails-extensions/extensions/quarter_dates.rb
|
76
|
+
- lib/ruby-rails-extensions/extensions/range_add.rb
|
77
|
+
- lib/ruby-rails-extensions/extensions/range_multiply.rb
|
62
78
|
- lib/ruby-rails-extensions/extensions/remove_reserved_keywords.rb
|
79
|
+
- lib/ruby-rails-extensions/extensions/safe_parse.rb
|
80
|
+
- lib/ruby-rails-extensions/extensions/select_present.rb
|
81
|
+
- lib/ruby-rails-extensions/extensions/select_present_join.rb
|
82
|
+
- lib/ruby-rails-extensions/extensions/set_to_sentence.rb
|
63
83
|
- lib/ruby-rails-extensions/extensions/to_bool.rb
|
64
84
|
- lib/ruby-rails-extensions/extensions/to_dec.rb
|
65
85
|
- lib/ruby-rails-extensions/extensions/to_i.rb
|
86
|
+
- lib/ruby-rails-extensions/extensions/to_local.rb
|
87
|
+
- lib/ruby-rails-extensions/extensions/to_negative_i.rb
|
88
|
+
- lib/ruby-rails-extensions/extensions/to_nonzero_i.rb
|
66
89
|
- lib/ruby-rails-extensions/extensions/to_or_sentence.rb
|
90
|
+
- lib/ruby-rails-extensions/extensions/to_positive_i.rb
|
67
91
|
- lib/ruby-rails-extensions/extensions/to_sort_i.rb
|
68
92
|
- lib/ruby-rails-extensions/extensions/to_x.rb
|
93
|
+
- lib/ruby-rails-extensions/extensions/todays_date.rb
|
94
|
+
- lib/ruby-rails-extensions/extensions/uniq_map.rb
|
69
95
|
- lib/ruby-rails-extensions/extensions/usd_to_f.rb
|
70
96
|
- lib/ruby-rails-extensions/extensions/usd_to_i.rb
|
97
|
+
- lib/ruby-rails-extensions/extensions/weighted_sum.rb
|
71
98
|
- lib/ruby-rails-extensions/extensions/yesno.rb
|
99
|
+
- lib/ruby-rails-extensions/extensions/zero_range.rb
|
72
100
|
- lib/ruby-rails-extensions/version.rb
|
73
101
|
homepage: https://github.com/BrandsInsurance/rails-extensions
|
74
102
|
licenses:
|