CHANGELOG.md 18.4 KB
Newer Older
G
George Claghorn 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
## Rails 6.0.1.rc1 (October 31, 2019) ##

*   `ActiveSupport::SafeBuffer` supports `Enumerator` methods.

    *Shugo Maeda*

*   The Redis cache store fails gracefully when the server returns a "max number
    of clients reached" error.

    *Brandon Medenwald*

*   Fixed that mutating a value returned by a memory cache store would
    unexpectedly change the cached value.

    *Jonathan Hyman*

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
*   The default inflectors in `zeitwerk` mode support overrides:

    ```ruby
    # config/initializers/zeitwerk.rb
    Rails.autoloaders.each do |autoloader|
      autoloader.inflector.inflect(
        "html_parser" => "HTMLParser",
        "ssl_error"   => "SSLError"
      )
    end
    ```

    That way, you can tweak how individual basenames are inflected without touching Active Support inflection rules, which are global. These inflectors fallback to `String#camelize`, so existing inflection rules are still taken into account for non-overridden basenames.

    Please, check the [autoloading guide for `zeitwerk` mode](https://guides.rubyonrails.org/v6.0/autoloading_and_reloading_constants.html#customizing-inflections) if you prefer not to depend on `String#camelize` at all.

    *Xavier Noria*

35 36
*   Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
    and endless range targets.
37

38
    *Allen Hsu*, *Andrew Hodgkinson*
39

40 41 42 43
*   Don't use `Process#clock_gettime(CLOCK_PROCESS_CPUTIME_ID)` on Solaris

    *Iain Beeston*

G
George Claghorn 已提交
44

45 46
## Rails 6.0.0 (August 16, 2019) ##

47 48 49 50 51 52 53 54 55 56
*   Let `require_dependency` in `zeitwerk` mode look the autoload paths up for
    better backwards compatibility.

    *Xavier Noria*

*   Let `require_dependency` in `zeitwerk` mode support arguments that respond
    to `to_path` for better backwards compatibility.

    *Xavier Noria*

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
*   Make ActiveSupport::Logger Fiber-safe. Fixes #36752.

    Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order
    to make log level local to Ruby Fibers in addition to Threads.

    Example:

        logger = ActiveSupport::Logger.new(STDOUT)
        logger.level = 1
        p "Main is debug? #{logger.debug?}"

        Fiber.new {
          logger.local_level = 0
          p "Thread is debug? #{logger.debug?}"
        }.resume

        p "Main is debug? #{logger.debug?}"

    Before:

        Main is debug? false
        Thread is debug? true
        Main is debug? true

    After:

        Main is debug? false
        Thread is debug? true
        Main is debug? false

    *Alexander Varnin*

89 90 91 92 93 94 95
*   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*

G
George Claghorn 已提交
96

97 98
## Rails 6.0.0.rc2 (July 22, 2019) ##

J
Jordan Thomas 已提交
99 100 101 102 103 104 105
*   `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:

106 107 108 109
        'foobar'.truncate(5).frozen?
        # => true
        'foobar'.truncate(6).frozen?
        # => false
J
Jordan Thomas 已提交
110 111 112

    After:

113 114 115 116
        'foobar'.truncate(5).frozen?
        # => false
        'foobar'.truncate(6).frozen?
        # => false
J
Jordan Thomas 已提交
117 118 119 120

    *Jordan Thomas*


121 122
## Rails 6.0.0.rc1 (April 24, 2019) ##

G
Genadi Samokovarov 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
*   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*

155 156 157 158 159 160 161 162 163 164 165 166
*   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*

167 168 169 170 171
*   Calling test methods with `with_info_handler` method to allow minitest-hooks
    plugin to work.

    *Mauri Mustonen*

X
Xavier Noria 已提交
172 173 174 175 176 177 178 179
*   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 已提交
180 181 182 183 184 185
*   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*

186 187 188 189 190 191 192 193 194
*   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*

195 196 197 198
*   Fix bug in Range comparisons when comparing to an excluded-end Range

    Before:

199
        (1..10).cover?(1...11) # => false
200 201 202

    After:

203
        (1..10).cover?(1...11) # => true
204 205 206

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

207
    *Owen Stephens*
208

209 210 211 212 213
*   Use weak references in descendants tracker to allow anonymous subclasses to
    be garbage collected.

    *Edgars Beigarts*

A
Ali Ibrahim 已提交
214
*   Update `ActiveSupport::Notifications::Instrumenter#instrument` to make
A
Ali Ibrahim 已提交
215 216 217 218 219 220
    passing a block optional. This will let users use
    `ActiveSupport::Notifications` messaging features outside of
    instrumentation.

    *Ali Ibrahim*

221 222 223
*   Fix `Time#advance` to work with dates before 1001-03-07

    Before:
224

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

227
    After
228

229 230 231 232 233 234
        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*

235 236 237 238
*   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*

239
*   Add support for supplying `locale` to `transliterate` and `parameterize`.
240 241 242

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

243 244 245
        ActiveSupport::Inflector.transliterate("ü", locale: :de) # => "ue"
        "Fünf autos".parameterize(locale: :de) # => "fuenf-autos"
        ActiveSupport::Inflector.parameterize("Fünf autos", locale: :de) # => "fuenf-autos"
246 247 248

    *Kaan Ozkan*, *Sharang Dashputre*

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

251
        [ 1, 2, 3, 4, 5 ].excluding([4, 5]) # => [ 1, 2, 3 ]
252 253 254

    *DHH*

255 256
*   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.
257 258 259

    *DHH*

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

262 263
        [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
        post.authors.including(Current.person) # => All the authors plus the current person!
264 265 266

    *DHH*

267

E
eileencodes 已提交
268 269 270 271 272
## Rails 6.0.0.beta3 (March 11, 2019) ##

*   No changes.


273 274
## Rails 6.0.0.beta2 (February 25, 2019) ##

275 276 277 278
*   New autoloading based on [Zeitwerk](https://github.com/fxn/zeitwerk).

    *Xavier Noria*

Z
zvkemp 已提交
279 280 281 282
*   Revise `ActiveSupport::Notifications.unsubscribe` to correctly handle Regex or other multiple-pattern subscribers.

    *Zach Kemp*

283 284 285 286
*   Add `before_reset` callback to `CurrentAttributes` and define `after_reset` as an alias of `resets` for symmetry.

    *Rosa Gutierrez*

287
*   Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems.
288 289 290

    *Akinori Musha*

291 292 293 294 295 296
*   Add `ActiveSupport::HashWithIndifferentAccess#assoc`.

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

    *Stefan Schüßler*

297 298 299 300
*   Add `Hash#deep_transform_values`, and `Hash#deep_transform_values!`.

    *Guillermo Iguaran*

301

302 303
## Rails 6.0.0.beta1 (January 18, 2019) ##

304 305 306 307
*   Remove deprecated `Module#reachable?` method.

    *Rafael Mendonça França*

308 309 310 311
*   Remove deprecated `#acronym_regex` method from `Inflections`.

    *Rafael Mendonça França*

312 313 314 315
*   Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.

    *Keenan Brock*

316 317 318 319 320 321
*   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*

322 323 324 325
*   If the same block is `included` multiple times for a Concern, an exception is no longer raised.

    *Mark J. Titorenko*, *Vlad Bokov*

326 327 328 329 330
*   Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
    would not act as alias for `#symbolize_keys`.

    *Nick Weiland*

331 332 333 334
*   Improve the logic that detects non-autoloaded constants.

    *Jan Habermann*, *Xavier Noria*

335 336 337 338 339
*   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*

340 341 342 343
*   Deprecate `ActiveSupport::Multibyte::Chars.consumes?` in favor of `String#is_utf8?`.

    *Francesco Rodríguez*

344 345 346 347 348 349 350 351 352
*   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*

353 354 355 356 357
*   Deprecate `ActiveSupport::Multibyte::Unicode#normalize` and `ActiveSuppport::Multibyte::Chars#normalize`
    in favor of `String#unicode_normalize`

    *Francesco Rodríguez*

358 359 360 361 362
*   Deprecate `ActiveSupport::Multibyte::Unicode#downcase/upcase/swapcase` in favor of
    `String#downcase/upcase/swapcase`.

    *Francesco Rodríguez*

363 364 365 366
*   Add `ActiveSupport::ParameterFilter`.

    *Yoshiyuki Kinjo*

367 368 369 370 371
*   Rename `Module#parent`, `Module#parents`, and `Module#parent_name` to
    `module_parent`, `module_parents`, and `module_parent_name`.

    *Gannon McGibbon*

372 373 374 375
*   Deprecate the use of `LoggerSilence` in favor of `ActiveSupport::LoggerSilence`

    *Edouard Chin*

376 377 378 379
*   Deprecate using negative limits in `String#first` and `String#last`.

    *Gannon McGibbon*, *Eric Turner*

380 381 382 383 384
*   Fix bug where `#without` for `ActiveSupport::HashWithIndifferentAccess` would fail
    with symbol arguments

    *Abraham Chan*

385 386 387 388 389
*   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*

390 391
*   Changed `ActiveSupport::TaggedLogging.new` to return a new logger instance instead
    of mutating the one received as parameter.
392 393 394

    *Thierry Joyal*

395 396 397 398 399 400
*   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 已提交
401 402 403 404 405 406 407 408 409
*   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 已提交
410
*   Maintain `html_safe?` on html_safe strings when sliced.
411 412 413 414

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

R
Ryuta Kamizono 已提交
415
    *Elom Gomez*, *Yumin Wong*
416

B
bogdanvlviv 已提交
417 418 419 420 421 422 423 424 425 426 427
*   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*

428 429 430 431 432 433 434
*   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 已提交
435
*   Add "event object" support to the notification system.
A
Aaron Patterson 已提交
436
    Before this change, end users were forced to create hand made artisanal
A
Aaron Patterson 已提交
437 438 439 440 441
    event objects on their own, like this:

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

A
Aaron Patterson 已提交
443 444 445
        ActiveSupport::Notifications.instrument('wait') do
          sleep 1
        end
446

A
Aaron Patterson 已提交
447 448 449 450 451 452 453 454 455
        @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
456

A
Aaron Patterson 已提交
457 458 459
        ActiveSupport::Notifications.instrument('wait') do
          sleep 1
        end
460

A
Aaron Patterson 已提交
461 462 463 464 465 466 467 468
        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 已提交
469
*   Add cpu_time, idle_time, and allocations to Event.
470 471 472

    *Eileen M. Uchitelle*, *Aaron Patterson*

K
Kasper Timm Hansen 已提交
473 474 475 476 477 478 479 480 481 482
*   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 已提交
483
*   Allow `Range#===` and `Range#cover?` on Range.
U
utilum 已提交
484 485 486 487 488 489 490 491 492 493

    `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*

494 495 496 497 498 499 500 501 502 503 504
*   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 }

505
    Closely linked with `index_by`, which creates a hash where the keys are extracted from a block.
506 507 508

    *Kasper Timm Hansen*

509
*   Fix bug where `ActiveSupport::TimeZone.all` would fail when tzinfo data for
510
    any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
511 512 513

    *Dominik Sander*

514 515 516 517 518
*   Redis cache store: `delete_matched` no longer blocks the Redis server.
    (Switches from evaled Lua to a batched SCAN + DEL loop.)

    *Gleb Mazovetskiy*

519 520 521 522 523 524 525
*   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*

526
*   Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
527 528 529 530 531 532 533

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

    *Ashe Connor*, *Aaron Patterson*

534 535 536 537 538
*   Add `before?` and `after?` methods to `Date`, `DateTime`,
    `Time`, and `TimeWithZone`.

    *Nick Holden*

539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
*   `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*

567 568
*   Add `:private` option to ActiveSupport's `Module#delegate`
    in order to delegate methods as private:
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584

        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*

585 586 587 588 589
*   `String#truncate_bytes` to truncate a string to a maximum bytesize without
    breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦.

    *Jeremy Daer*

590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
*   `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 已提交
606
*   Rails 6 requires Ruby 2.5.0 or newer.
J
Jeremy Daer 已提交
607

K
Kasper Timm Hansen 已提交
608
    *Jeremy Daer*, *Kasper Timm Hansen*
J
Jeremy Daer 已提交
609

B
bogdanvlviv 已提交
610
*   Adds parallel testing to Rails.
J
Jeremy Daer 已提交
611 612 613 614

    Parallelize your test suite with forked processes or threads.

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

616

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