activesupport 4.1.16 → 4.2.0.beta1
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 +140 -714
- data/README.rdoc +7 -2
- data/lib/active_support/backtrace_cleaner.rb +4 -4
- data/lib/active_support/cache.rb +18 -20
- data/lib/active_support/cache/file_store.rb +5 -0
- data/lib/active_support/cache/strategy/local_cache.rb +5 -4
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +5 -0
- data/lib/active_support/callbacks.rb +92 -140
- data/lib/active_support/concern.rb +9 -1
- data/lib/active_support/core_ext/array/access.rb +5 -1
- data/lib/active_support/core_ext/array/grouping.rb +5 -0
- data/lib/active_support/core_ext/class/delegating_attributes.rb +4 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +11 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/hash.rb +1 -0
- data/lib/active_support/core_ext/hash/conversions.rb +2 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +10 -6
- data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
- data/lib/active_support/core_ext/kernel.rb +3 -2
- data/lib/active_support/core_ext/kernel/concern.rb +10 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +14 -0
- data/lib/active_support/core_ext/load_error.rb +4 -1
- data/lib/active_support/core_ext/module/delegation.rb +13 -25
- data/lib/active_support/core_ext/numeric/time.rb +1 -19
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/duplicable.rb +4 -11
- data/lib/active_support/core_ext/object/itself.rb +12 -0
- data/lib/active_support/core_ext/object/json.rb +1 -1
- data/lib/active_support/core_ext/object/to_query.rb +2 -1
- data/lib/active_support/core_ext/object/with_options.rb +15 -2
- data/lib/active_support/core_ext/string/access.rb +4 -4
- data/lib/active_support/core_ext/string/filters.rb +25 -1
- data/lib/active_support/core_ext/string/inflections.rb +3 -1
- data/lib/active_support/core_ext/string/output_safety.rb +29 -19
- data/lib/active_support/core_ext/thread.rb +7 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -1
- data/lib/active_support/core_ext/time/zones.rb +0 -1
- data/lib/active_support/dependencies.rb +5 -4
- data/lib/active_support/duration.rb +2 -3
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +13 -5
- data/lib/active_support/i18n_railtie.rb +1 -7
- data/lib/active_support/inflector/inflections.rb +1 -1
- data/lib/active_support/inflector/methods.rb +39 -15
- data/lib/active_support/json/encoding.rb +0 -4
- data/lib/active_support/logger.rb +0 -14
- data/lib/active_support/logger_silence.rb +3 -24
- data/lib/active_support/message_encryptor.rb +2 -1
- data/lib/active_support/multibyte/unicode.rb +5 -3
- data/lib/active_support/notifications.rb +7 -2
- data/lib/active_support/notifications/fanout.rb +11 -6
- data/lib/active_support/number_helper.rb +7 -8
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -2
- data/lib/active_support/test_case.rb +3 -13
- data/lib/active_support/testing/assertions.rb +1 -1
- data/lib/active_support/testing/declarative.rb +1 -25
- data/lib/active_support/testing/isolation.rb +16 -6
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +5 -1
- data/lib/active_support/time.rb +0 -2
- data/lib/active_support/time_with_zone.rb +14 -3
- data/lib/active_support/values/time_zone.rb +76 -75
- data/lib/active_support/xml_mini.rb +0 -3
- data/lib/active_support/xml_mini/jdom.rb +5 -6
- data/lib/active_support/xml_mini/rexml.rb +5 -6
- metadata +17 -16
- data/lib/active_support/core_ext/object/to_json.rb +0 -5
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/security_utils.rb +0 -27
@@ -19,7 +19,7 @@
|
|
19
19
|
class Object
|
20
20
|
# Can you safely dup this object?
|
21
21
|
#
|
22
|
-
# False for +nil+, +false+, +true+, symbol, and
|
22
|
+
# False for +nil+, +false+, +true+, symbol, number and BigDecimal(in 1.9.x) objects;
|
23
23
|
# true otherwise.
|
24
24
|
def duplicable?
|
25
25
|
true
|
@@ -78,6 +78,9 @@ end
|
|
78
78
|
|
79
79
|
require 'bigdecimal'
|
80
80
|
class BigDecimal
|
81
|
+
# Needed to support Ruby 1.9.x, as it doesn't allow dup on BigDecimal, instead
|
82
|
+
# raises TypeError exception. Checking here on the runtime whether BigDecimal
|
83
|
+
# will allow dup or not.
|
81
84
|
begin
|
82
85
|
BigDecimal.new('4.56').dup
|
83
86
|
|
@@ -88,13 +91,3 @@ class BigDecimal
|
|
88
91
|
# can't dup, so use superclass implementation
|
89
92
|
end
|
90
93
|
end
|
91
|
-
|
92
|
-
class Method
|
93
|
-
# Methods are not duplicable:
|
94
|
-
#
|
95
|
-
# method(:puts).duplicable? # => false
|
96
|
-
# method(:puts).dup # => TypeError: allocator undefined for Method
|
97
|
-
def duplicable?
|
98
|
-
false
|
99
|
-
end
|
100
|
-
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Object
|
2
|
+
unless respond_to?(:itself) # TODO: Remove this file when we drop support for Ruby < 2.2
|
3
|
+
# Returns the object itself. Useful when dealing with a chaining scenario, like Active Record scopes:
|
4
|
+
#
|
5
|
+
# Event.public_send(state.presence_in([ :trashed, :drafted ]) || :itself).order(:created_at)
|
6
|
+
#
|
7
|
+
# @return Object
|
8
|
+
def itself
|
9
|
+
self
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -26,7 +26,7 @@ require 'active_support/core_ext/module/aliasing'
|
|
26
26
|
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
|
27
27
|
# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
|
28
28
|
# should give exactly the same results with or without active support.
|
29
|
-
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass|
|
29
|
+
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].each do |klass|
|
30
30
|
klass.class_eval do
|
31
31
|
def to_json_with_active_support_encoder(options = nil)
|
32
32
|
if options.is_a?(::JSON::State)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
1
3
|
class Object
|
2
4
|
# Alias of <tt>to_s</tt>.
|
3
5
|
def to_param
|
@@ -7,7 +9,6 @@ class Object
|
|
7
9
|
# Converts an object into a string suitable for use as a URL query string,
|
8
10
|
# using the given <tt>key</tt> as the param name.
|
9
11
|
def to_query(key)
|
10
|
-
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
11
12
|
"#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
|
12
13
|
end
|
13
14
|
end
|
@@ -34,9 +34,22 @@ class Object
|
|
34
34
|
# body i18n.t :body, user_name: user.name
|
35
35
|
# end
|
36
36
|
#
|
37
|
+
# When you don't pass an explicit receiver, it executes the whole block
|
38
|
+
# in merging options context:
|
39
|
+
#
|
40
|
+
# class Account < ActiveRecord::Base
|
41
|
+
# with_options dependent: :destroy do
|
42
|
+
# has_many :customers
|
43
|
+
# has_many :products
|
44
|
+
# has_many :invoices
|
45
|
+
# has_many :expenses
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
#
|
37
49
|
# <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
|
38
50
|
# Each nesting level will merge inherited defaults in addition to their own.
|
39
|
-
def with_options(options)
|
40
|
-
|
51
|
+
def with_options(options, &block)
|
52
|
+
option_merger = ActiveSupport::OptionMerger.new(self, options)
|
53
|
+
block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
|
41
54
|
end
|
42
55
|
end
|
@@ -64,7 +64,7 @@ class String
|
|
64
64
|
|
65
65
|
# Returns the first character. If a limit is supplied, returns a substring
|
66
66
|
# from the beginning of the string until it reaches the limit value. If the
|
67
|
-
# given limit is greater than or equal to the string length, returns self.
|
67
|
+
# given limit is greater than or equal to the string length, returns a copy of self.
|
68
68
|
#
|
69
69
|
# str = "hello"
|
70
70
|
# str.first # => "h"
|
@@ -76,7 +76,7 @@ class String
|
|
76
76
|
if limit == 0
|
77
77
|
''
|
78
78
|
elsif limit >= size
|
79
|
-
self
|
79
|
+
self.dup
|
80
80
|
else
|
81
81
|
to(limit - 1)
|
82
82
|
end
|
@@ -84,7 +84,7 @@ class String
|
|
84
84
|
|
85
85
|
# Returns the last character of the string. If a limit is supplied, returns a substring
|
86
86
|
# from the end of the string until it reaches the limit value (counting backwards). If
|
87
|
-
# the given limit is greater than or equal to the string length, returns self.
|
87
|
+
# the given limit is greater than or equal to the string length, returns a copy of self.
|
88
88
|
#
|
89
89
|
# str = "hello"
|
90
90
|
# str.last # => "o"
|
@@ -96,7 +96,7 @@ class String
|
|
96
96
|
if limit == 0
|
97
97
|
''
|
98
98
|
elsif limit >= size
|
99
|
-
self
|
99
|
+
self.dup
|
100
100
|
else
|
101
101
|
from(-limit)
|
102
102
|
end
|
@@ -3,7 +3,7 @@ class String
|
|
3
3
|
# the string, and then changing remaining consecutive whitespace
|
4
4
|
# groups into one space each.
|
5
5
|
#
|
6
|
-
# Note that it handles both ASCII and Unicode whitespace.
|
6
|
+
# Note that it handles both ASCII and Unicode whitespace like mongolian vowel separator (U+180E).
|
7
7
|
#
|
8
8
|
# %{ Multi-line
|
9
9
|
# string }.squish # => "Multi-line string"
|
@@ -62,4 +62,28 @@ class String
|
|
62
62
|
|
63
63
|
"#{self[0, stop]}#{omission}"
|
64
64
|
end
|
65
|
+
|
66
|
+
# Truncates a given +text+ after a given number of words (<tt>words_count</tt>):
|
67
|
+
#
|
68
|
+
# 'Once upon a time in a world far far away'.truncate_words(4)
|
69
|
+
# # => "Once upon a time..."
|
70
|
+
#
|
71
|
+
# Pass a string or regexp <tt>:separator</tt> to specify a different separator of words:
|
72
|
+
#
|
73
|
+
# 'Once<br>upon<br>a<br>time<br>in<br>a<br>world'.truncate_words(5, separator: '<br>')
|
74
|
+
# # => "Once<br>upon<br>a<br>time<br>in..."
|
75
|
+
#
|
76
|
+
# The last characters will be replaced with the <tt>:omission</tt> string (defaults to "..."):
|
77
|
+
#
|
78
|
+
# 'And they found that many people were sleeping better.'.truncate_words(5, omission: '... (continued)')
|
79
|
+
# # => "And they found that many... (continued)"
|
80
|
+
def truncate_words(words_count, options = {})
|
81
|
+
sep = options[:separator] || /\s+/
|
82
|
+
sep = Regexp.escape(sep.to_s) unless Regexp === sep
|
83
|
+
if self =~ /\A((?:.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m
|
84
|
+
$1 + (options[:omission] || '...')
|
85
|
+
else
|
86
|
+
dup
|
87
|
+
end
|
88
|
+
end
|
65
89
|
end
|
@@ -31,7 +31,7 @@ class String
|
|
31
31
|
def pluralize(count = nil, locale = :en)
|
32
32
|
locale = count if count.is_a?(Symbol)
|
33
33
|
if count == 1
|
34
|
-
self
|
34
|
+
self.dup
|
35
35
|
else
|
36
36
|
ActiveSupport::Inflector.pluralize(self, locale)
|
37
37
|
end
|
@@ -130,6 +130,8 @@ class String
|
|
130
130
|
#
|
131
131
|
# 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
|
132
132
|
# 'Inflections'.demodulize # => "Inflections"
|
133
|
+
# '::Inflections'.demodulize # => "Inflections"
|
134
|
+
# ''.demodulize # => ''
|
133
135
|
#
|
134
136
|
# See also +deconstantize+.
|
135
137
|
def demodulize
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'active_support/core_ext/kernel/singleton_class'
|
3
|
+
require 'active_support/deprecation'
|
3
4
|
|
4
5
|
class ERB
|
5
6
|
module Util
|
@@ -18,12 +19,7 @@ class ERB
|
|
18
19
|
# puts html_escape('is a > 0 & a < 10?')
|
19
20
|
# # => is a > 0 & a < 10?
|
20
21
|
def html_escape(s)
|
21
|
-
s
|
22
|
-
if s.html_safe?
|
23
|
-
s
|
24
|
-
else
|
25
|
-
s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE).html_safe
|
26
|
-
end
|
22
|
+
unwrapped_html_escape(s).html_safe
|
27
23
|
end
|
28
24
|
|
29
25
|
# Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
|
@@ -35,6 +31,18 @@ class ERB
|
|
35
31
|
singleton_class.send(:remove_method, :html_escape)
|
36
32
|
module_function :html_escape
|
37
33
|
|
34
|
+
# HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
|
35
|
+
# This method is not for public consumption! Seriously!
|
36
|
+
def unwrapped_html_escape(s) # :nodoc:
|
37
|
+
s = s.to_s
|
38
|
+
if s.html_safe?
|
39
|
+
s
|
40
|
+
else
|
41
|
+
s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
module_function :unwrapped_html_escape
|
45
|
+
|
38
46
|
# A utility method for escaping HTML without affecting existing escaped entities.
|
39
47
|
#
|
40
48
|
# html_escape_once('1 < 2 & 3')
|
@@ -124,7 +132,7 @@ module ActiveSupport #:nodoc:
|
|
124
132
|
class SafeBuffer < String
|
125
133
|
UNSAFE_STRING_METHODS = %w(
|
126
134
|
capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
|
127
|
-
slice squeeze strip sub succ swapcase tr tr_s upcase
|
135
|
+
slice squeeze strip sub succ swapcase tr tr_s upcase
|
128
136
|
)
|
129
137
|
|
130
138
|
alias_method :original_concat, :concat
|
@@ -142,11 +150,7 @@ module ActiveSupport #:nodoc:
|
|
142
150
|
else
|
143
151
|
if html_safe?
|
144
152
|
new_safe_buffer = super
|
145
|
-
|
146
|
-
if new_safe_buffer
|
147
|
-
new_safe_buffer.instance_eval { @html_safe = true }
|
148
|
-
end
|
149
|
-
|
153
|
+
new_safe_buffer.instance_eval { @html_safe = true }
|
150
154
|
new_safe_buffer
|
151
155
|
else
|
152
156
|
to_str[*args]
|
@@ -174,14 +178,19 @@ module ActiveSupport #:nodoc:
|
|
174
178
|
end
|
175
179
|
|
176
180
|
def concat(value)
|
177
|
-
|
178
|
-
super(value)
|
179
|
-
else
|
180
|
-
super(ERB::Util.h(value))
|
181
|
-
end
|
181
|
+
super(html_escape_interpolated_argument(value))
|
182
182
|
end
|
183
183
|
alias << concat
|
184
184
|
|
185
|
+
def prepend(value)
|
186
|
+
super(html_escape_interpolated_argument(value))
|
187
|
+
end
|
188
|
+
|
189
|
+
def prepend!(value)
|
190
|
+
ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend
|
191
|
+
prepend value
|
192
|
+
end
|
193
|
+
|
185
194
|
def +(other)
|
186
195
|
dup.concat(other)
|
187
196
|
end
|
@@ -210,7 +219,7 @@ module ActiveSupport #:nodoc:
|
|
210
219
|
end
|
211
220
|
|
212
221
|
def encode_with(coder)
|
213
|
-
coder.
|
222
|
+
coder.represent_scalar nil, to_str
|
214
223
|
end
|
215
224
|
|
216
225
|
UNSAFE_STRING_METHODS.each do |unsafe_method|
|
@@ -231,7 +240,8 @@ module ActiveSupport #:nodoc:
|
|
231
240
|
private
|
232
241
|
|
233
242
|
def html_escape_interpolated_argument(arg)
|
234
|
-
(!html_safe? || arg.html_safe?) ? arg :
|
243
|
+
(!html_safe? || arg.html_safe?) ? arg :
|
244
|
+
arg.to_s.gsub(ERB::Util::HTML_ESCAPE_REGEXP, ERB::Util::HTML_ESCAPE)
|
235
245
|
end
|
236
246
|
end
|
237
247
|
end
|
@@ -62,6 +62,13 @@ class Thread
|
|
62
62
|
_locals.has_key?(key.to_sym)
|
63
63
|
end
|
64
64
|
|
65
|
+
# Freezes the thread so that thread local variables cannot be set via
|
66
|
+
# Thread#thread_variable_set, nor can fiber local variables be set.
|
67
|
+
#
|
68
|
+
# me = Thread.current
|
69
|
+
# me.freeze
|
70
|
+
# me.thread_variable_set(:oliver, "a") #=> RuntimeError: can't modify frozen thread locals
|
71
|
+
# me[:oliver] = "a" #=> RuntimeError: can't modify frozen thread locals
|
65
72
|
def freeze
|
66
73
|
_locals.freeze
|
67
74
|
super
|
@@ -20,7 +20,7 @@ class Time
|
|
20
20
|
:iso8601 => lambda { |time| time.iso8601 }
|
21
21
|
}
|
22
22
|
|
23
|
-
# Converts to a formatted string. See DATE_FORMATS for
|
23
|
+
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
24
24
|
#
|
25
25
|
# This method is aliased to <tt>to_s</tt>.
|
26
26
|
#
|
@@ -180,10 +180,11 @@ module ActiveSupport #:nodoc:
|
|
180
180
|
Dependencies.load_missing_constant(from_mod, const_name)
|
181
181
|
end
|
182
182
|
|
183
|
-
#
|
184
|
-
# it can be proven that is not the case)
|
185
|
-
# defines the constant. Anonymous modules cannot follow these
|
186
|
-
# and we assume
|
183
|
+
# We assume that the name of the module reflects the nesting
|
184
|
+
# (unless it can be proven that is not the case) and the path to the file
|
185
|
+
# that defines the constant. Anonymous modules cannot follow these
|
186
|
+
# conventions and therefore we assume that the user wants to refer to a
|
187
|
+
# top-level constant.
|
187
188
|
def guess_for_anonymous(const_name)
|
188
189
|
if Object.const_defined?(const_name)
|
189
190
|
raise NameError.new "#{const_name} cannot be autoloaded from an anonymous class or module", const_name
|
@@ -78,7 +78,7 @@ module ActiveSupport
|
|
78
78
|
reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
|
79
79
|
sort_by {|unit, _ | [:years, :months, :days, :minutes, :seconds].index(unit)}.
|
80
80
|
map {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}.
|
81
|
-
to_sentence(locale:
|
81
|
+
to_sentence(:locale => :en)
|
82
82
|
end
|
83
83
|
|
84
84
|
def as_json(options = nil) #:nodoc:
|
@@ -105,8 +105,7 @@ module ActiveSupport
|
|
105
105
|
|
106
106
|
# We define it as a workaround to Ruby 2.0.0-p353 bug.
|
107
107
|
# For more information, check rails/rails#13055.
|
108
|
-
#
|
109
|
-
# release after 2.0.0-p353 happens.
|
108
|
+
# Remove it when we drop support for 2.0.0-p353.
|
110
109
|
def ===(other) #:nodoc:
|
111
110
|
value === other
|
112
111
|
end
|
@@ -55,7 +55,7 @@ module ActiveSupport
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def initialize(constructor = {})
|
58
|
-
if constructor.
|
58
|
+
if constructor.respond_to?(:to_hash)
|
59
59
|
super()
|
60
60
|
update(constructor)
|
61
61
|
else
|
@@ -75,6 +75,7 @@ module ActiveSupport
|
|
75
75
|
hash = hash.to_hash
|
76
76
|
new(hash).tap do |new_hash|
|
77
77
|
new_hash.default = hash.default
|
78
|
+
new_hash.default_proc = hash.default_proc if hash.default_proc
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
@@ -176,7 +177,14 @@ module ActiveSupport
|
|
176
177
|
indices.collect { |key| self[convert_key(key)] }
|
177
178
|
end
|
178
179
|
|
179
|
-
# Returns
|
180
|
+
# Returns a shallow copy of the hash.
|
181
|
+
#
|
182
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
183
|
+
# dup = hash.dup
|
184
|
+
# dup[:a][:c] = 'c'
|
185
|
+
#
|
186
|
+
# hash[:a][:c] # => nil
|
187
|
+
# dup[:a][:c] # => "c"
|
180
188
|
def dup
|
181
189
|
self.class.new(self).tap do |new_hash|
|
182
190
|
new_hash.default = default
|
@@ -238,11 +246,11 @@ module ActiveSupport
|
|
238
246
|
|
239
247
|
# Convert to a regular hash with string keys.
|
240
248
|
def to_hash
|
241
|
-
_new_hash=
|
249
|
+
_new_hash = Hash.new(default)
|
242
250
|
each do |key, value|
|
243
|
-
_new_hash[
|
251
|
+
_new_hash[key] = convert_value(value, for: :to_hash)
|
244
252
|
end
|
245
|
-
|
253
|
+
_new_hash
|
246
254
|
end
|
247
255
|
|
248
256
|
protected
|
@@ -8,8 +8,6 @@ module I18n
|
|
8
8
|
config.i18n.railties_load_path = []
|
9
9
|
config.i18n.load_path = []
|
10
10
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
11
|
-
# Enforce I18n to check the available locales when setting a locale.
|
12
|
-
config.i18n.enforce_available_locales = true
|
13
11
|
|
14
12
|
# Set the i18n configuration after initialization since a lot of
|
15
13
|
# configuration is still usually done in application initializers.
|
@@ -36,11 +34,7 @@ module I18n
|
|
36
34
|
# Avoid issues with setting the default_locale by disabling available locales
|
37
35
|
# check while configuring.
|
38
36
|
enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
|
39
|
-
|
40
|
-
if enforce_available_locales.nil?
|
41
|
-
enforce_available_locales = I18n.enforce_available_locales
|
42
|
-
end
|
43
|
-
|
37
|
+
enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
|
44
38
|
I18n.enforce_available_locales = false
|
45
39
|
|
46
40
|
app.config.i18n.each do |setting, value|
|
@@ -160,7 +160,7 @@ module ActiveSupport
|
|
160
160
|
# uncountable 'money', 'information'
|
161
161
|
# uncountable %w( money information rice )
|
162
162
|
def uncountable(*words)
|
163
|
-
|
163
|
+
@uncountables += words.flatten.map(&:downcase)
|
164
164
|
end
|
165
165
|
|
166
166
|
# Specifies a humanized form of a string by a regular expression rule or
|