activesupport 5.1.7 → 5.2.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +424 -512
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +2 -0
- data/lib/active_support/backtrace_cleaner.rb +2 -0
- data/lib/active_support/benchmarkable.rb +2 -0
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +5 -4
- data/lib/active_support/cache/mem_cache_store.rb +39 -38
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/null_store.rb +2 -0
- data/lib/active_support/cache/redis_cache_store.rb +466 -0
- data/lib/active_support/cache/strategy/local_cache.rb +33 -2
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +197 -83
- data/lib/active_support/callbacks.rb +28 -39
- data/lib/active_support/concern.rb +10 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -0
- data/lib/active_support/configurable.rb +2 -0
- data/lib/active_support/core_ext/array/access.rb +4 -2
- data/lib/active_support/core_ext/array/conversions.rb +2 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +2 -0
- data/lib/active_support/core_ext/array/inquiry.rb +2 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -2
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +2 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +34 -16
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +1 -2
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +2 -0
- data/lib/active_support/core_ext/date/calculations.rb +2 -0
- data/lib/active_support/core_ext/date/conversions.rb +10 -9
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +50 -16
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +3 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +2 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +2 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +3 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +8 -1
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/compact.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +4 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/except.rb +2 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +2 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +4 -4
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -0
- data/lib/active_support/core_ext/hash.rb +2 -0
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +2 -0
- data/lib/active_support/core_ext/load_error.rb +2 -7
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -24
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -0
- data/lib/active_support/core_ext/module/concerning.rb +7 -8
- data/lib/active_support/core_ext/module/delegation.rb +31 -29
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +2 -0
- data/lib/active_support/core_ext/module/reachable.rb +3 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -0
- data/lib/active_support/core_ext/name_error.rb +7 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +9 -7
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -0
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +12 -1
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +2 -0
- data/lib/active_support/core_ext/object/duplicable.rb +10 -8
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +2 -0
- data/lib/active_support/core_ext/object/try.rb +2 -0
- data/lib/active_support/core_ext/object/with_options.rb +3 -1
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +9 -1
- data/lib/active_support/core_ext/range/each.rb +5 -1
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +2 -0
- data/lib/active_support/core_ext/string/access.rb +2 -0
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +2 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +2 -0
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +26 -12
- data/lib/active_support/core_ext/string/inquiry.rb +2 -0
- data/lib/active_support/core_ext/string/multibyte.rb +4 -0
- data/lib/active_support/core_ext/string/output_safety.rb +6 -7
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +2 -0
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +23 -15
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +6 -6
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/dependencies.rb +25 -26
- data/lib/active_support/deprecation/behaviors.rb +28 -9
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/instance_delegator.rb +2 -0
- data/lib/active_support/deprecation/method_wrappers.rb +30 -17
- data/lib/active_support/deprecation/proxy_wrappers.rb +5 -2
- data/lib/active_support/deprecation/reporting.rb +5 -3
- data/lib/active_support/deprecation.rb +4 -2
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +4 -2
- data/lib/active_support/duration/iso8601_serializer.rb +4 -2
- data/lib/active_support/duration.rb +22 -14
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +2 -0
- data/lib/active_support/execution_wrapper.rb +18 -13
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -0
- data/lib/active_support/gem_version.rb +3 -1
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +55 -1
- data/lib/active_support/i18n.rb +3 -1
- data/lib/active_support/i18n_railtie.rb +4 -6
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +20 -4
- data/lib/active_support/inflector/methods.rb +43 -24
- data/lib/active_support/inflector/transliterate.rb +17 -8
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/json/decoding.rb +2 -0
- data/lib/active_support/json/encoding.rb +2 -0
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -1
- data/lib/active_support/lazy_load_hooks.rb +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/log_subscriber.rb +3 -2
- data/lib/active_support/logger.rb +2 -0
- data/lib/active_support/logger_silence.rb +3 -2
- data/lib/active_support/logger_thread_safe_level.rb +4 -1
- data/lib/active_support/message_encryptor.rb +95 -22
- data/lib/active_support/message_verifier.rb +78 -7
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +2 -0
- data/lib/active_support/multibyte/unicode.rb +4 -2
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +4 -2
- data/lib/active_support/notifications/instrumenter.rb +2 -0
- data/lib/active_support/notifications.rb +2 -0
- data/lib/active_support/number_helper/number_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -20
- data/lib/active_support/number_helper/rounding_helper.rb +6 -4
- data/lib/active_support/number_helper.rb +2 -0
- data/lib/active_support/option_merger.rb +2 -0
- data/lib/active_support/ordered_hash.rb +2 -0
- data/lib/active_support/ordered_options.rb +5 -3
- data/lib/active_support/per_thread_registry.rb +2 -0
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +2 -0
- data/lib/active_support/railtie.rb +37 -8
- data/lib/active_support/reloader.rb +8 -6
- data/lib/active_support/rescuable.rb +3 -2
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +2 -0
- data/lib/active_support/subscriber.rb +8 -2
- data/lib/active_support/tagged_logging.rb +2 -0
- data/lib/active_support/test_case.rb +3 -2
- data/lib/active_support/testing/assertions.rb +31 -14
- data/lib/active_support/testing/autorun.rb +2 -0
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +2 -0
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +3 -1
- data/lib/active_support/testing/method_call_assertions.rb +2 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +2 -0
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +33 -3
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +38 -0
- data/lib/active_support/values/time_zone.rb +20 -8
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +4 -2
- data/lib/active_support/xml_mini/libxml.rb +3 -1
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -2
- data/lib/active_support/xml_mini/nokogiri.rb +3 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
- data/lib/active_support/xml_mini/rexml.rb +3 -1
- data/lib/active_support/xml_mini.rb +4 -2
- data/lib/active_support.rb +5 -13
- metadata +17 -5
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/duration"
|
2
4
|
require "active_support/core_ext/time/conversions"
|
3
5
|
require "active_support/time_with_zone"
|
@@ -107,21 +109,22 @@ class Time
|
|
107
109
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
108
110
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
109
111
|
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
110
|
-
# and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
111
|
-
#
|
112
|
-
# <tt>:
|
113
|
-
# <tt>:
|
112
|
+
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
113
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
114
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
115
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
114
116
|
#
|
115
117
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
116
118
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
117
119
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
118
120
|
def change(options)
|
119
|
-
new_year
|
120
|
-
new_month
|
121
|
-
new_day
|
122
|
-
new_hour
|
123
|
-
new_min
|
124
|
-
new_sec
|
121
|
+
new_year = options.fetch(:year, year)
|
122
|
+
new_month = options.fetch(:month, month)
|
123
|
+
new_day = options.fetch(:day, day)
|
124
|
+
new_hour = options.fetch(:hour, hour)
|
125
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
126
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
127
|
+
new_offset = options.fetch(:offset, nil)
|
125
128
|
|
126
129
|
if new_nsec = options[:nsec]
|
127
130
|
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
@@ -130,13 +133,18 @@ class Time
|
|
130
133
|
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
131
134
|
end
|
132
135
|
|
133
|
-
if
|
134
|
-
|
136
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
137
|
+
|
138
|
+
new_sec += Rational(new_usec, 1000000)
|
139
|
+
|
140
|
+
if new_offset
|
141
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
142
|
+
elsif utc?
|
143
|
+
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
135
144
|
elsif zone
|
136
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
145
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
137
146
|
else
|
138
|
-
|
139
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
|
147
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
140
148
|
end
|
141
149
|
end
|
142
150
|
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/date_and_time/compatibility"
|
2
|
-
require "active_support/core_ext/module/
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
3
5
|
|
4
6
|
class Time
|
5
7
|
include DateAndTime::Compatibility
|
6
8
|
|
7
|
-
|
9
|
+
silence_redefinition_of_method :to_time
|
8
10
|
|
9
11
|
# Either return +self+ or the time in the local system timezone depending
|
10
12
|
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/time_with_zone"
|
2
4
|
require "active_support/core_ext/time/acts_like"
|
3
5
|
require "active_support/core_ext/date_and_time/zones"
|
@@ -53,10 +55,10 @@ class Time
|
|
53
55
|
# end
|
54
56
|
# end
|
55
57
|
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
58
|
+
# NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
|
59
|
+
# objects that have already been created, e.g. any model timestamp
|
60
|
+
# attributes that have been read before the block will remain in
|
61
|
+
# the application's default timezone.
|
60
62
|
def use_zone(time_zone)
|
61
63
|
new_zone = find_zone!(time_zone)
|
62
64
|
begin
|
@@ -1,16 +1,16 @@
|
|
1
|
-
|
2
|
-
str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
|
3
|
-
parser = URI::Parser.new
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
3
|
+
require "uri"
|
4
|
+
if RUBY_VERSION < "2.6.0"
|
5
|
+
require "active_support/core_ext/module/redefine_method"
|
6
6
|
URI::Parser.class_eval do
|
7
|
-
|
7
|
+
silence_redefinition_of_method :unescape
|
8
8
|
def unescape(str, escaped = /%[a-fA-F\d]{2}/)
|
9
9
|
# TODO: Are we actually sure that ASCII == UTF-8?
|
10
10
|
# YK: My initial experiments say yes, but let's be sure please
|
11
11
|
enc = str.encoding
|
12
12
|
enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
|
13
|
-
str.gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
|
13
|
+
str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
# Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
|
5
|
+
# before and after each request. This allows you to keep all the per-request attributes easily
|
6
|
+
# available to the whole system.
|
7
|
+
#
|
8
|
+
# The following full app-like example demonstrates how to use a Current class to
|
9
|
+
# facilitate easy access to the global, per-request attributes without passing them deeply
|
10
|
+
# around everywhere:
|
11
|
+
#
|
12
|
+
# # app/models/current.rb
|
13
|
+
# class Current < ActiveSupport::CurrentAttributes
|
14
|
+
# attribute :account, :user
|
15
|
+
# attribute :request_id, :user_agent, :ip_address
|
16
|
+
#
|
17
|
+
# resets { Time.zone = nil }
|
18
|
+
#
|
19
|
+
# def user=(user)
|
20
|
+
# super
|
21
|
+
# self.account = user.account
|
22
|
+
# Time.zone = user.time_zone
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # app/controllers/concerns/authentication.rb
|
27
|
+
# module Authentication
|
28
|
+
# extend ActiveSupport::Concern
|
29
|
+
#
|
30
|
+
# included do
|
31
|
+
# before_action :authenticate
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# private
|
35
|
+
# def authenticate
|
36
|
+
# if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
|
37
|
+
# Current.user = authenticated_user
|
38
|
+
# else
|
39
|
+
# redirect_to new_session_url
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# # app/controllers/concerns/set_current_request_details.rb
|
45
|
+
# module SetCurrentRequestDetails
|
46
|
+
# extend ActiveSupport::Concern
|
47
|
+
#
|
48
|
+
# included do
|
49
|
+
# before_action do
|
50
|
+
# Current.request_id = request.uuid
|
51
|
+
# Current.user_agent = request.user_agent
|
52
|
+
# Current.ip_address = request.ip
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# class ApplicationController < ActionController::Base
|
58
|
+
# include Authentication
|
59
|
+
# include SetCurrentRequestDetails
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# class MessagesController < ApplicationController
|
63
|
+
# def create
|
64
|
+
# Current.account.messages.create(message_params)
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# class Message < ApplicationRecord
|
69
|
+
# belongs_to :creator, default: -> { Current.user }
|
70
|
+
# after_create { |message| Event.create(record: message) }
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# class Event < ApplicationRecord
|
74
|
+
# before_create do
|
75
|
+
# self.request_id = Current.request_id
|
76
|
+
# self.user_agent = Current.user_agent
|
77
|
+
# self.ip_address = Current.ip_address
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result.
|
82
|
+
# Current should only be used for a few, top-level globals, like account, user, and request details.
|
83
|
+
# The attributes stuck in Current should be used by more or less all actions on all requests. If you start
|
84
|
+
# sticking controller-specific attributes in there, you're going to create a mess.
|
85
|
+
class CurrentAttributes
|
86
|
+
include ActiveSupport::Callbacks
|
87
|
+
define_callbacks :reset
|
88
|
+
|
89
|
+
class << self
|
90
|
+
# Returns singleton instance for this class in this thread. If none exists, one is created.
|
91
|
+
def instance
|
92
|
+
current_instances[name] ||= new
|
93
|
+
end
|
94
|
+
|
95
|
+
# Declares one or more attributes that will be given both class and instance accessor methods.
|
96
|
+
def attribute(*names)
|
97
|
+
generated_attribute_methods.module_eval do
|
98
|
+
names.each do |name|
|
99
|
+
define_method(name) do
|
100
|
+
attributes[name.to_sym]
|
101
|
+
end
|
102
|
+
|
103
|
+
define_method("#{name}=") do |attribute|
|
104
|
+
attributes[name.to_sym] = attribute
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
names.each do |name|
|
110
|
+
define_singleton_method(name) do
|
111
|
+
instance.public_send(name)
|
112
|
+
end
|
113
|
+
|
114
|
+
define_singleton_method("#{name}=") do |attribute|
|
115
|
+
instance.public_send("#{name}=", attribute)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Calls this block after #reset is called on the instance. Used for resetting external collaborators, like Time.zone.
|
121
|
+
def resets(&block)
|
122
|
+
set_callback :reset, :after, &block
|
123
|
+
end
|
124
|
+
|
125
|
+
delegate :set, :reset, to: :instance
|
126
|
+
|
127
|
+
def reset_all # :nodoc:
|
128
|
+
current_instances.each_value(&:reset)
|
129
|
+
end
|
130
|
+
|
131
|
+
def clear_all # :nodoc:
|
132
|
+
reset_all
|
133
|
+
current_instances.clear
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
def generated_attribute_methods
|
138
|
+
@generated_attribute_methods ||= Module.new.tap { |mod| include mod }
|
139
|
+
end
|
140
|
+
|
141
|
+
def current_instances
|
142
|
+
Thread.current[:current_attributes_instances] ||= {}
|
143
|
+
end
|
144
|
+
|
145
|
+
def method_missing(name, *args, &block)
|
146
|
+
# Caches the method definition as a singleton method of the receiver.
|
147
|
+
#
|
148
|
+
# By letting #delegate handle it, we avoid an enclosure that'll capture args.
|
149
|
+
singleton_class.delegate name, to: :instance
|
150
|
+
|
151
|
+
send(name, *args, &block)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
attr_accessor :attributes
|
156
|
+
|
157
|
+
def initialize
|
158
|
+
@attributes = {}
|
159
|
+
end
|
160
|
+
|
161
|
+
# Expose one or more attributes within a block. Old values are returned after the block concludes.
|
162
|
+
# Example demonstrating the common use of needing to set Current attributes outside the request-cycle:
|
163
|
+
#
|
164
|
+
# class Chat::PublicationJob < ApplicationJob
|
165
|
+
# def perform(attributes, room_number, creator)
|
166
|
+
# Current.set(person: creator) do
|
167
|
+
# Chat::Publisher.publish(attributes: attributes, room_number: room_number)
|
168
|
+
# end
|
169
|
+
# end
|
170
|
+
# end
|
171
|
+
def set(set_attributes)
|
172
|
+
old_attributes = compute_attributes(set_attributes.keys)
|
173
|
+
assign_attributes(set_attributes)
|
174
|
+
yield
|
175
|
+
ensure
|
176
|
+
assign_attributes(old_attributes)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Reset all attributes. Should be called before and after actions, when used as a per-request singleton.
|
180
|
+
def reset
|
181
|
+
run_callbacks :reset do
|
182
|
+
self.attributes = {}
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
def assign_attributes(new_attributes)
|
188
|
+
new_attributes.each { |key, value| public_send("#{key}=", value) }
|
189
|
+
end
|
190
|
+
|
191
|
+
def compute_attributes(keys)
|
192
|
+
keys.collect { |key| [ key, public_send(key) ] }.to_h
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
2
4
|
require "thread"
|
3
5
|
require "concurrent/map"
|
@@ -18,8 +20,7 @@ module ActiveSupport #:nodoc:
|
|
18
20
|
module Dependencies #:nodoc:
|
19
21
|
extend self
|
20
22
|
|
21
|
-
mattr_accessor :interlock
|
22
|
-
self.interlock = Interlock.new
|
23
|
+
mattr_accessor :interlock, default: Interlock.new
|
23
24
|
|
24
25
|
# :doc:
|
25
26
|
|
@@ -46,46 +47,37 @@ module ActiveSupport #:nodoc:
|
|
46
47
|
# :nodoc:
|
47
48
|
|
48
49
|
# Should we turn on Ruby warnings on the first load of dependent files?
|
49
|
-
mattr_accessor :warnings_on_first_load
|
50
|
-
self.warnings_on_first_load = false
|
50
|
+
mattr_accessor :warnings_on_first_load, default: false
|
51
51
|
|
52
52
|
# All files ever loaded.
|
53
|
-
mattr_accessor :history
|
54
|
-
self.history = Set.new
|
53
|
+
mattr_accessor :history, default: Set.new
|
55
54
|
|
56
55
|
# All files currently loaded.
|
57
|
-
mattr_accessor :loaded
|
58
|
-
self.loaded = Set.new
|
56
|
+
mattr_accessor :loaded, default: Set.new
|
59
57
|
|
60
58
|
# Stack of files being loaded.
|
61
|
-
mattr_accessor :loading
|
62
|
-
self.loading = []
|
59
|
+
mattr_accessor :loading, default: []
|
63
60
|
|
64
61
|
# Should we load files or require them?
|
65
|
-
mattr_accessor :mechanism
|
66
|
-
self.mechanism = ENV["NO_RELOAD"] ? :require : :load
|
62
|
+
mattr_accessor :mechanism, default: ENV["NO_RELOAD"] ? :require : :load
|
67
63
|
|
68
64
|
# The set of directories from which we may automatically load files. Files
|
69
65
|
# under these directories will be reloaded on each request in development mode,
|
70
66
|
# unless the directory also appears in autoload_once_paths.
|
71
|
-
mattr_accessor :autoload_paths
|
72
|
-
self.autoload_paths = []
|
67
|
+
mattr_accessor :autoload_paths, default: []
|
73
68
|
|
74
69
|
# The set of directories from which automatically loaded constants are loaded
|
75
70
|
# only once. All directories in this set must also be present in +autoload_paths+.
|
76
|
-
mattr_accessor :autoload_once_paths
|
77
|
-
self.autoload_once_paths = []
|
71
|
+
mattr_accessor :autoload_once_paths, default: []
|
78
72
|
|
79
73
|
# An array of qualified constant names that have been loaded. Adding a name
|
80
74
|
# to this array will cause it to be unloaded the next time Dependencies are
|
81
75
|
# cleared.
|
82
|
-
mattr_accessor :autoloaded_constants
|
83
|
-
self.autoloaded_constants = []
|
76
|
+
mattr_accessor :autoloaded_constants, default: []
|
84
77
|
|
85
78
|
# An array of constant names that need to be unloaded on every request. Used
|
86
79
|
# to allow arbitrary constants to be marked for unloading.
|
87
|
-
mattr_accessor :explicitly_unloadable_constants
|
88
|
-
self.explicitly_unloadable_constants = []
|
80
|
+
mattr_accessor :explicitly_unloadable_constants, default: []
|
89
81
|
|
90
82
|
# The WatchStack keeps a stack of the modules being watched as files are
|
91
83
|
# loaded. If a file in the process of being loaded (parent.rb) triggers the
|
@@ -93,7 +85,7 @@ module ActiveSupport #:nodoc:
|
|
93
85
|
# handles the new constants.
|
94
86
|
#
|
95
87
|
# If child.rb is being autoloaded, its constants will be added to
|
96
|
-
# autoloaded_constants. If it was being
|
88
|
+
# autoloaded_constants. If it was being required, they will be discarded.
|
97
89
|
#
|
98
90
|
# This is handled by walking back up the watch stack and adding the constants
|
99
91
|
# found by child.rb to the list of original constants in parent.rb.
|
@@ -105,6 +97,8 @@ module ActiveSupport #:nodoc:
|
|
105
97
|
# parent.rb then requires namespace/child.rb, the stack will look like
|
106
98
|
# [[Object], [Namespace]].
|
107
99
|
|
100
|
+
attr_reader :watching
|
101
|
+
|
108
102
|
def initialize
|
109
103
|
@watching = []
|
110
104
|
@stack = Hash.new { |h, k| h[k] = [] }
|
@@ -175,8 +169,7 @@ module ActiveSupport #:nodoc:
|
|
175
169
|
end
|
176
170
|
|
177
171
|
# An internal stack used to record which constants are loaded by any block.
|
178
|
-
mattr_accessor :constant_watch_stack
|
179
|
-
self.constant_watch_stack = WatchStack.new
|
172
|
+
mattr_accessor :constant_watch_stack, default: WatchStack.new
|
180
173
|
|
181
174
|
# Module includes this module.
|
182
175
|
module ModuleConstMissing #:nodoc:
|
@@ -233,6 +226,8 @@ module ActiveSupport #:nodoc:
|
|
233
226
|
Dependencies.require_or_load(file_name)
|
234
227
|
end
|
235
228
|
|
229
|
+
# :doc:
|
230
|
+
|
236
231
|
# Interprets a file using <tt>mechanism</tt> and marks its defined
|
237
232
|
# constants as autoloaded. <tt>file_name</tt> can be either a string or
|
238
233
|
# respond to <tt>to_path</tt>.
|
@@ -251,9 +246,13 @@ module ActiveSupport #:nodoc:
|
|
251
246
|
Dependencies.depend_on(file_name, message)
|
252
247
|
end
|
253
248
|
|
249
|
+
# :nodoc:
|
250
|
+
|
254
251
|
def load_dependency(file)
|
255
252
|
if Dependencies.load? && Dependencies.constant_watch_stack.watching?
|
256
|
-
Dependencies.
|
253
|
+
descs = Dependencies.constant_watch_stack.watching.flatten.uniq
|
254
|
+
|
255
|
+
Dependencies.new_constants_in(*descs) { yield }
|
257
256
|
else
|
258
257
|
yield
|
259
258
|
end
|
@@ -625,7 +624,7 @@ module ActiveSupport #:nodoc:
|
|
625
624
|
return false if desc.is_a?(Module) && desc.anonymous?
|
626
625
|
name = to_constant_name desc
|
627
626
|
return false unless qualified_const_defined?(name)
|
628
|
-
|
627
|
+
autoloaded_constants.include?(name)
|
629
628
|
end
|
630
629
|
|
631
630
|
# Will the provided constant descriptor be unloaded?
|
@@ -680,7 +679,7 @@ module ActiveSupport #:nodoc:
|
|
680
679
|
when Module
|
681
680
|
desc.name ||
|
682
681
|
raise(ArgumentError, "Anonymous modules have no name to be referenced by")
|
683
|
-
|
682
|
+
else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
|
684
683
|
end
|
685
684
|
end
|
686
685
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/notifications"
|
2
4
|
|
3
5
|
module ActiveSupport
|
@@ -9,18 +11,18 @@ module ActiveSupport
|
|
9
11
|
class Deprecation
|
10
12
|
# Default warning behaviors per Rails.env.
|
11
13
|
DEFAULT_BEHAVIORS = {
|
12
|
-
raise: ->(message, callstack) {
|
14
|
+
raise: ->(message, callstack, deprecation_horizon, gem_name) {
|
13
15
|
e = DeprecationException.new(message)
|
14
16
|
e.set_backtrace(callstack.map(&:to_s))
|
15
17
|
raise e
|
16
18
|
},
|
17
19
|
|
18
|
-
stderr: ->(message, callstack) {
|
20
|
+
stderr: ->(message, callstack, deprecation_horizon, gem_name) {
|
19
21
|
$stderr.puts(message)
|
20
22
|
$stderr.puts callstack.join("\n ") if debug
|
21
23
|
},
|
22
24
|
|
23
|
-
log: ->(message, callstack) {
|
25
|
+
log: ->(message, callstack, deprecation_horizon, gem_name) {
|
24
26
|
logger =
|
25
27
|
if defined?(Rails.logger) && Rails.logger
|
26
28
|
Rails.logger
|
@@ -32,12 +34,16 @@ module ActiveSupport
|
|
32
34
|
logger.debug callstack.join("\n ") if debug
|
33
35
|
},
|
34
36
|
|
35
|
-
notify: ->(message, callstack) {
|
36
|
-
|
37
|
-
|
37
|
+
notify: ->(message, callstack, deprecation_horizon, gem_name) {
|
38
|
+
notification_name = "deprecation.#{gem_name.underscore.tr('/', '_')}"
|
39
|
+
ActiveSupport::Notifications.instrument(notification_name,
|
40
|
+
message: message,
|
41
|
+
callstack: callstack,
|
42
|
+
gem_name: gem_name,
|
43
|
+
deprecation_horizon: deprecation_horizon)
|
38
44
|
},
|
39
45
|
|
40
|
-
silence: ->(message, callstack) {},
|
46
|
+
silence: ->(message, callstack, deprecation_horizon, gem_name) {},
|
41
47
|
}
|
42
48
|
|
43
49
|
# Behavior module allows to determine how to display deprecation messages.
|
@@ -79,12 +85,25 @@ module ActiveSupport
|
|
79
85
|
# ActiveSupport::Deprecation.behavior = :stderr
|
80
86
|
# ActiveSupport::Deprecation.behavior = [:stderr, :log]
|
81
87
|
# ActiveSupport::Deprecation.behavior = MyCustomHandler
|
82
|
-
# ActiveSupport::Deprecation.behavior = ->(message, callstack) {
|
88
|
+
# ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
|
83
89
|
# # custom stuff
|
84
90
|
# }
|
85
91
|
def behavior=(behavior)
|
86
|
-
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
|
92
|
+
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
87
93
|
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def arity_coerce(behavior)
|
97
|
+
unless behavior.respond_to?(:call)
|
98
|
+
raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
|
99
|
+
end
|
100
|
+
|
101
|
+
if behavior.arity == 4 || behavior.arity == -1
|
102
|
+
behavior
|
103
|
+
else
|
104
|
+
-> message, callstack, _, _ { behavior.call(message, callstack) }
|
105
|
+
end
|
106
|
+
end
|
88
107
|
end
|
89
108
|
end
|
90
109
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
4
|
class Deprecation
|
@@ -15,7 +15,7 @@ module ActiveSupport
|
|
15
15
|
#
|
16
16
|
# PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
|
17
17
|
#
|
18
|
-
# (In a later update, the original implementation of `PLANETS` has been removed.)
|
18
|
+
# # (In a later update, the original implementation of `PLANETS` has been removed.)
|
19
19
|
#
|
20
20
|
# PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
|
21
21
|
# include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
@@ -27,6 +27,8 @@ module ActiveSupport
|
|
27
27
|
# ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
|
28
28
|
module DeprecatedConstantAccessor
|
29
29
|
def self.included(base)
|
30
|
+
require "active_support/inflector/methods"
|
31
|
+
|
30
32
|
extension = Module.new do
|
31
33
|
def const_missing(missing_const_name)
|
32
34
|
if class_variable_defined?(:@@_deprecated_constants)
|