CHANGELOG.md 15.9 KB
Newer Older
1 2 3 4 5 6 7
*   Do not delegate missing `marshal_dump` and `_dump` methods via the
    `delegate_missing_to` extension. This avoids unintentionally adding instance
    variables when calling `Marshal.dump(object)`, should the delegation target of
    `object` be a method which would otherwise add them. Fixes #36522.

    *Aaron Lipman*

J
Jordan Thomas 已提交
8 9 10 11 12 13 14
*   `truncate` would return the original string if it was too short to be truncated
    and a frozen string if it were long enough to be truncated. Now truncate will
    consistently return an unfrozen string regardless. This behavior is consistent
    with `gsub` and `strip`.

    Before:

15 16 17 18
        'foobar'.truncate(5).frozen?
        # => true
        'foobar'.truncate(6).frozen?
        # => false
J
Jordan Thomas 已提交
19 20 21

    After:

22 23 24 25
        'foobar'.truncate(5).frozen?
        # => false
        'foobar'.truncate(6).frozen?
        # => false
J
Jordan Thomas 已提交
26 27 28 29

    *Jordan Thomas*


30 31
## Rails 6.0.0.rc1 (April 24, 2019) ##

G
Genadi Samokovarov 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
*   Introduce `ActiveSupport::ActionableError`.

    Actionable errors let's you dispatch actions from Rails' error pages. This
    can help you save time if you have a clear action for the resolution of
    common development errors.

    The de-facto example are pending migrations. Every time pending migrations
    are found, a middleware raises an error. With actionable errors, you can
    run the migrations right from the error page. Other examples include Rails
    plugins that need to run a rake task to setup themselves. They can now
    raise actionable errors to run the setup straight from the error pages.

    Here is how to define an actionable error:

    ```ruby
    class PendingMigrationError < MigrationError #:nodoc:
      include ActiveSupport::ActionableError

      action "Run pending migrations" do
        ActiveRecord::Tasks::DatabaseTasks.migrate
      end
    end
    ```

    To make an error actionable, include the `ActiveSupport::ActionableError`
    module and invoke the `action` class macro to define the action. An action
    needs a name and a procedure to execute. The name is shown as the name of a
    button on the error pages. Once clicked, it will invoke the given
    procedure.

    *Vipul A M*, *Yao Jie*, *Genadi Samokovarov*

64 65 66 67 68 69 70 71 72 73 74 75
*   Preserve `html_safe?` status on `ActiveSupport::SafeBuffer#*`.

    Before:

        ("<br />".html_safe * 2).html_safe? #=> nil

    After:

        ("<br />".html_safe * 2).html_safe? #=> true

    *Ryo Nakamura*

76 77 78 79 80
*   Calling test methods with `with_info_handler` method to allow minitest-hooks
    plugin to work.

    *Mauri Mustonen*

X
Xavier Noria 已提交
81 82 83 84 85 86 87 88
*   The Zeitwerk compatibility interface for `ActiveSupport::Dependencies` no
    longer implements `autoloaded_constants` or `autoloaded?` (undocumented,
    anyway). Experience shows introspection does not have many use cases, and
    troubleshooting is done by logging. With this design trade-off we are able
    to use even less memory in all environments.

    *Xavier Noria*

X
Xavier Noria 已提交
89 90 91 92 93 94
*   Depends on Zeitwerk 2, which stores less metadata if reloading is disabled
    and hence uses less memory when `config.cache_classes` is `true`, a standard
    setup in production.

    *Xavier Noria*

95 96 97 98 99 100 101 102 103
*   In `:zeitwerk` mode, eager load directories in engines and applications only
    if present in their respective `config.eager_load_paths`.

    A common use case for this is adding `lib` to `config.autoload_paths`, but
    not to `config.eager_load_paths`. In that configuration, for example, files
    in the `lib` directory should not be eager loaded.

    *Xavier Noria*

104 105 106 107
*   Fix bug in Range comparisons when comparing to an excluded-end Range

    Before:

108
        (1..10).cover?(1...11) # => false
109 110 111

    After:

112
        (1..10).cover?(1...11) # => true
113 114 115

    With the same change for `Range#include?` and `Range#===`.

116
    *Owen Stephens*
117

118 119 120 121 122
*   Use weak references in descendants tracker to allow anonymous subclasses to
    be garbage collected.

    *Edgars Beigarts*

A
Ali Ibrahim 已提交
123
*   Update `ActiveSupport::Notifications::Instrumenter#instrument` to make
A
Ali Ibrahim 已提交
124 125 126 127 128 129
    passing a block optional. This will let users use
    `ActiveSupport::Notifications` messaging features outside of
    instrumentation.

    *Ali Ibrahim*

130 131 132
*   Fix `Time#advance` to work with dates before 1001-03-07

    Before:
133

134
        Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-05 00:00:00 UTC
135

136
    After
137

138 139 140 141 142 143
        Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-06 00:00:00 UTC

    Note that this doesn't affect `DateTime#advance` as that doesn't use a proleptic calendar.

    *Andrew White*

144 145 146 147
*   In Zeitwerk mode, engines are now managed by the `main` autoloader. Engines may reference application constants, if the application is reloaded and we do not reload engines, they won't use the reloaded application code.

    *Xavier Noria*

148
*   Add support for supplying `locale` to `transliterate` and `parameterize`.
149 150 151

        I18n.backend.store_translations(:de, i18n: { transliterate: { rule: { "ü" => "ue" } } })

152 153 154
        ActiveSupport::Inflector.transliterate("ü", locale: :de) # => "ue"
        "Fünf autos".parameterize(locale: :de) # => "fuenf-autos"
        ActiveSupport::Inflector.parameterize("Fünf autos", locale: :de) # => "fuenf-autos"
155 156 157

    *Kaan Ozkan*, *Sharang Dashputre*

158
*   Allow `Array#excluding` and `Enumerable#excluding` to deal with a passed array gracefully.
159

160
        [ 1, 2, 3, 4, 5 ].excluding([4, 5]) # => [ 1, 2, 3 ]
161 162 163

    *DHH*

164 165
*   Renamed `Array#without` and `Enumerable#without` to `Array#excluding` and `Enumerable#excluding`, to create parity with
    `Array#including` and `Enumerable#including`. Retained the old names as aliases.
166 167 168

    *DHH*

169
*   Added `Array#including` and `Enumerable#including` to conveniently enlarge a collection with more members using a method rather than an operator:
170

171 172
        [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
        post.authors.including(Current.person) # => All the authors plus the current person!
173 174 175

    *DHH*

176

E
eileencodes 已提交
177 178 179 180 181
## Rails 6.0.0.beta3 (March 11, 2019) ##

*   No changes.


182 183
## Rails 6.0.0.beta2 (February 25, 2019) ##

184 185 186 187
*   New autoloading based on [Zeitwerk](https://github.com/fxn/zeitwerk).

    *Xavier Noria*

Z
zvkemp 已提交
188 189 190 191
*   Revise `ActiveSupport::Notifications.unsubscribe` to correctly handle Regex or other multiple-pattern subscribers.

    *Zach Kemp*

192 193 194 195
*   Add `before_reset` callback to `CurrentAttributes` and define `after_reset` as an alias of `resets` for symmetry.

    *Rosa Gutierrez*

196
*   Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems.
197 198 199

    *Akinori Musha*

200 201 202 203 204 205
*   Add `ActiveSupport::HashWithIndifferentAccess#assoc`.

    `assoc` can now be called with either a string or a symbol.

    *Stefan Schüßler*

206 207 208 209
*   Add `Hash#deep_transform_values`, and `Hash#deep_transform_values!`.

    *Guillermo Iguaran*

210

211 212
## Rails 6.0.0.beta1 (January 18, 2019) ##

213 214 215 216
*   Remove deprecated `Module#reachable?` method.

    *Rafael Mendonça França*

217 218 219 220
*   Remove deprecated `#acronym_regex` method from `Inflections`.

    *Rafael Mendonça França*

221 222 223 224
*   Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.

    *Keenan Brock*

225 226 227 228 229 230
*   Preserve key order passed to `ActiveSupport::CacheStore#fetch_multi`.

    `fetch_multi(*names)` now returns its results in the same order as the `*names` requested, rather than returning cache hits followed by cache misses.

    *Gannon McGibbon*

231 232 233 234
*   If the same block is `included` multiple times for a Concern, an exception is no longer raised.

    *Mark J. Titorenko*, *Vlad Bokov*

235 236 237 238 239
*   Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
    would not act as alias for `#symbolize_keys`.

    *Nick Weiland*

240 241 242 243
*   Improve the logic that detects non-autoloaded constants.

    *Jan Habermann*, *Xavier Noria*

244 245 246 247 248
*   Deprecate `ActiveSupport::Multibyte::Unicode#pack_graphemes(array)` and `ActiveSuppport::Multibyte::Unicode#unpack_graphemes(string)`
    in favor of `array.flatten.pack("U*")` and `string.scan(/\X/).map(&:codepoints)`, respectively.

    *Francesco Rodríguez*

249 250 251 252
*   Deprecate `ActiveSupport::Multibyte::Chars.consumes?` in favor of `String#is_utf8?`.

    *Francesco Rodríguez*

253 254 255 256 257 258 259 260 261
*   Fix duration being rounded to a full second.
    ```
      time = DateTime.parse("2018-1-1")
      time += 0.51.seconds
    ```
    Will now correctly add 0.51 second and not 1 full second.

    *Edouard Chin*

262 263 264 265 266
*   Deprecate `ActiveSupport::Multibyte::Unicode#normalize` and `ActiveSuppport::Multibyte::Chars#normalize`
    in favor of `String#unicode_normalize`

    *Francesco Rodríguez*

267 268 269 270 271
*   Deprecate `ActiveSupport::Multibyte::Unicode#downcase/upcase/swapcase` in favor of
    `String#downcase/upcase/swapcase`.

    *Francesco Rodríguez*

272 273 274 275
*   Add `ActiveSupport::ParameterFilter`.

    *Yoshiyuki Kinjo*

276 277 278 279 280
*   Rename `Module#parent`, `Module#parents`, and `Module#parent_name` to
    `module_parent`, `module_parents`, and `module_parent_name`.

    *Gannon McGibbon*

281 282 283 284
*   Deprecate the use of `LoggerSilence` in favor of `ActiveSupport::LoggerSilence`

    *Edouard Chin*

285 286 287 288
*   Deprecate using negative limits in `String#first` and `String#last`.

    *Gannon McGibbon*, *Eric Turner*

289 290 291 292 293
*   Fix bug where `#without` for `ActiveSupport::HashWithIndifferentAccess` would fail
    with symbol arguments

    *Abraham Chan*

294 295 296 297 298
*   Treat `#delete_prefix`, `#delete_suffix` and `#unicode_normalize` results as non-`html_safe`.
    Ensure safety of arguments for `#insert`, `#[]=` and `#replace` calls on `html_safe` Strings.

    *Janosch Müller*

299 300
*   Changed `ActiveSupport::TaggedLogging.new` to return a new logger instance instead
    of mutating the one received as parameter.
301 302 303

    *Thierry Joyal*

304 305 306 307 308 309
*   Define `unfreeze_time` as an alias of `travel_back` in `ActiveSupport::Testing::TimeHelpers`.

    The alias is provided for symmetry with `freeze_time`.

    *Ryan Davidson*

X
Xavier Noria 已提交
310 311 312 313 314 315 316 317 318
*   Add support for tracing constant autoloads. Just throw

        ActiveSupport::Dependencies.logger = Rails.logger
        ActiveSupport::Dependencies.verbose = true

    in an initializer.

    *Xavier Noria*

R
Ryuta Kamizono 已提交
319
*   Maintain `html_safe?` on html_safe strings when sliced.
320 321 322 323

        string = "<div>test</div>".html_safe
        string[-1..1].html_safe? # => true

R
Ryuta Kamizono 已提交
324
    *Elom Gomez*, *Yumin Wong*
325

B
bogdanvlviv 已提交
326 327 328 329 330 331 332 333 334 335 336
*   Add `Array#extract!`.

    The method removes and returns the elements for which the block returns a true value.
    If no block is given, an Enumerator is returned instead.

        numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
        numbers # => [0, 2, 4, 6, 8]

    *bogdanvlviv*

337 338 339 340 341 342 343
*   Support not to cache `nil` for `ActiveSupport::Cache#fetch`.

        cache.fetch('bar', skip_nil: true) { nil }
        cache.exist?('bar') # => false

    *Martin Hong*

A
Aaron Patterson 已提交
344
*   Add "event object" support to the notification system.
A
Aaron Patterson 已提交
345
    Before this change, end users were forced to create hand made artisanal
A
Aaron Patterson 已提交
346 347 348 349 350
    event objects on their own, like this:

        ActiveSupport::Notifications.subscribe('wait') do |*args|
          @event = ActiveSupport::Notifications::Event.new(*args)
        end
351

A
Aaron Patterson 已提交
352 353 354
        ActiveSupport::Notifications.instrument('wait') do
          sleep 1
        end
355

A
Aaron Patterson 已提交
356 357 358 359 360 361 362 363 364
        @event.duration # => 1000.138

    After this change, if the block passed to `subscribe` only takes one
    parameter, the framework will yield an event object to the block.  Now
    end users are no longer required to make their own:

        ActiveSupport::Notifications.subscribe('wait') do |event|
          @event = event
        end
365

A
Aaron Patterson 已提交
366 367 368
        ActiveSupport::Notifications.instrument('wait') do
          sleep 1
        end
369

A
Aaron Patterson 已提交
370 371 372 373 374 375 376 377
        p @event.allocations # => 7
        p @event.cpu_time    # => 0.256
        p @event.idle_time   # => 1003.2399

    Now you can enjoy event objects without making them yourself.  Neat!

    *Aaron "t.lo" Patterson*

R
Ryuta Kamizono 已提交
378
*   Add cpu_time, idle_time, and allocations to Event.
379 380 381

    *Eileen M. Uchitelle*, *Aaron Patterson*

K
Kasper Timm Hansen 已提交
382 383 384 385 386 387 388 389 390 391
*   RedisCacheStore: support key expiry in increment/decrement.

    Pass `:expires_in` to `#increment` and `#decrement` to set a Redis EXPIRE on the key.

    If the key is already set to expire, RedisCacheStore won't extend its expiry.

        Rails.cache.increment("some_key", 1, expires_in: 2.minutes)

    *Jason Lee*

R
Ryuta Kamizono 已提交
392
*   Allow `Range#===` and `Range#cover?` on Range.
U
utilum 已提交
393 394 395 396 397 398 399 400 401 402

    `Range#cover?` can now accept a range argument like `Range#include?` and
    `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
    into a new file, with these two methods.

    *Requiring active_support/core_ext/range/include_range is now deprecated.*
    *Use `require "active_support/core_ext/range/compare_range"` instead.*

    *utilum*

403 404 405 406 407 408 409 410 411 412 413
*   Add `index_with` to Enumerable.

    Allows creating a hash from an enumerable with the value from a passed block
    or a default argument.

        %i( title body ).index_with { |attr| post.public_send(attr) }
        # => { title: "hey", body: "what's up?" }

        %i( title body ).index_with(nil)
        # => { title: nil, body: nil }

414
    Closely linked with `index_by`, which creates a hash where the keys are extracted from a block.
415 416 417

    *Kasper Timm Hansen*

418
*   Fix bug where `ActiveSupport::TimeZone.all` would fail when tzinfo data for
419
    any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
420 421 422

    *Dominik Sander*

423 424 425 426 427
*   Redis cache store: `delete_matched` no longer blocks the Redis server.
    (Switches from evaled Lua to a batched SCAN + DEL loop.)

    *Gleb Mazovetskiy*

428 429 430 431 432 433 434
*   Fix bug where `ActiveSupport::Cache` will massively inflate the storage
    size when compression is enabled (which is true by default). This patch
    does not attempt to repair existing data: please manually flush the cache
    to clear out the problematic entries.

    *Godfrey Chan*

435
*   Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
436 437 438 439 440 441 442

        URI.unescape("\xe3\x83\x90")  # => "バ"
        URI.unescape("%E3%83%90")  # => "バ"
        URI.unescape("\xe3\x83\x90%E3%83%90")  # => Encoding::CompatibilityError

    *Ashe Connor*, *Aaron Patterson*

443 444 445 446 447
*   Add `before?` and `after?` methods to `Date`, `DateTime`,
    `Time`, and `TimeWithZone`.

    *Nick Holden*

448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
*   `ActiveSupport::Inflector#ordinal` and `ActiveSupport::Inflector#ordinalize` now support
    translations through I18n.

        # locale/fr.rb

        {
          fr: {
            number: {
              nth: {
                ordinals: lambda do |_key, number:, **_options|
                  if number.to_i.abs == 1
                    'er'
                  else
                    'e'
                  end
                end,

                ordinalized: lambda do |_key, number:, **_options|
                  "#{number}#{ActiveSupport::Inflector.ordinal(number)}"
                end
              }
            }
          }
        }


    *Christian Blais*

476 477
*   Add `:private` option to ActiveSupport's `Module#delegate`
    in order to delegate methods as private:
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493

        class User < ActiveRecord::Base
          has_one :profile
          delegate :date_of_birth, to: :profile, private: true

          def age
            Date.today.year - date_of_birth.year
          end
        end

        # User.new.age  # => 29
        # User.new.date_of_birth
        # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>

    *Tomas Valent*

494 495 496 497 498
*   `String#truncate_bytes` to truncate a string to a maximum bytesize without
    breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦.

    *Jeremy Daer*

499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
*   `String#strip_heredoc` preserves frozenness.

        "foo".freeze.strip_heredoc.frozen?  # => true

    Fixes that frozen string literals would inadvertently become unfrozen:

        # frozen_string_literal: true

        foo = <<-MSG.strip_heredoc
          la la la
        MSG

        foo.frozen?  # => false !??

    *Jeremy Daer*

K
Kasper Timm Hansen 已提交
515
*   Rails 6 requires Ruby 2.5.0 or newer.
J
Jeremy Daer 已提交
516

K
Kasper Timm Hansen 已提交
517
    *Jeremy Daer*, *Kasper Timm Hansen*
J
Jeremy Daer 已提交
518

B
bogdanvlviv 已提交
519
*   Adds parallel testing to Rails.
J
Jeremy Daer 已提交
520 521 522 523

    Parallelize your test suite with forked processes or threads.

    *Eileen M. Uchitelle*, *Aaron Patterson*
E
eileencodes 已提交
524

525

526
Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activesupport/CHANGELOG.md) for previous changes.