CHANGELOG.md 15.6 KB
Newer Older
J
Jordan Thomas 已提交
1 2 3 4 5 6 7
*   `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:

8 9 10 11
        'foobar'.truncate(5).frozen?
        # => true
        'foobar'.truncate(6).frozen?
        # => false
J
Jordan Thomas 已提交
12 13 14

    After:

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

    *Jordan Thomas*


23 24
## Rails 6.0.0.rc1 (April 24, 2019) ##

G
Genadi Samokovarov 已提交
25 26 27 28 29 30 31 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
*   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*

57 58 59 60 61 62 63 64 65 66 67 68
*   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*

69 70 71 72 73
*   Calling test methods with `with_info_handler` method to allow minitest-hooks
    plugin to work.

    *Mauri Mustonen*

X
Xavier Noria 已提交
74 75 76 77 78 79 80 81
*   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 已提交
82 83 84 85 86 87
*   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*

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

97 98 99 100
*   Fix bug in Range comparisons when comparing to an excluded-end Range

    Before:

101
        (1..10).cover?(1...11) # => false
102 103 104

    After:

105
        (1..10).cover?(1...11) # => true
106 107 108

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

109
    *Owen Stephens*
110

111 112 113 114 115
*   Use weak references in descendants tracker to allow anonymous subclasses to
    be garbage collected.

    *Edgars Beigarts*

A
Ali Ibrahim 已提交
116
*   Update `ActiveSupport::Notifications::Instrumenter#instrument` to make
A
Ali Ibrahim 已提交
117 118 119 120 121 122
    passing a block optional. This will let users use
    `ActiveSupport::Notifications` messaging features outside of
    instrumentation.

    *Ali Ibrahim*

123 124 125
*   Fix `Time#advance` to work with dates before 1001-03-07

    Before:
126

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

129
    After
130

131 132 133 134 135 136
        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*

137 138 139 140
*   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*

141
*   Add support for supplying `locale` to `transliterate` and `parameterize`.
142 143 144

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

145 146 147
        ActiveSupport::Inflector.transliterate("ü", locale: :de) # => "ue"
        "Fünf autos".parameterize(locale: :de) # => "fuenf-autos"
        ActiveSupport::Inflector.parameterize("Fünf autos", locale: :de) # => "fuenf-autos"
148 149 150

    *Kaan Ozkan*, *Sharang Dashputre*

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

153
        [ 1, 2, 3, 4, 5 ].excluding([4, 5]) # => [ 1, 2, 3 ]
154 155 156

    *DHH*

157 158
*   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.
159 160 161

    *DHH*

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

164 165
        [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
        post.authors.including(Current.person) # => All the authors plus the current person!
166 167 168

    *DHH*

169

E
eileencodes 已提交
170 171 172 173 174
## Rails 6.0.0.beta3 (March 11, 2019) ##

*   No changes.


175 176
## Rails 6.0.0.beta2 (February 25, 2019) ##

177 178 179 180
*   New autoloading based on [Zeitwerk](https://github.com/fxn/zeitwerk).

    *Xavier Noria*

Z
zvkemp 已提交
181 182 183 184
*   Revise `ActiveSupport::Notifications.unsubscribe` to correctly handle Regex or other multiple-pattern subscribers.

    *Zach Kemp*

185 186 187 188
*   Add `before_reset` callback to `CurrentAttributes` and define `after_reset` as an alias of `resets` for symmetry.

    *Rosa Gutierrez*

189
*   Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems.
190 191 192

    *Akinori Musha*

193 194 195 196 197 198
*   Add `ActiveSupport::HashWithIndifferentAccess#assoc`.

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

    *Stefan Schüßler*

199 200 201 202
*   Add `Hash#deep_transform_values`, and `Hash#deep_transform_values!`.

    *Guillermo Iguaran*

203

204 205
## Rails 6.0.0.beta1 (January 18, 2019) ##

206 207 208 209
*   Remove deprecated `Module#reachable?` method.

    *Rafael Mendonça França*

210 211 212 213
*   Remove deprecated `#acronym_regex` method from `Inflections`.

    *Rafael Mendonça França*

214 215 216 217
*   Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.

    *Keenan Brock*

218 219 220 221 222 223
*   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*

224 225 226 227
*   If the same block is `included` multiple times for a Concern, an exception is no longer raised.

    *Mark J. Titorenko*, *Vlad Bokov*

228 229 230 231 232
*   Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
    would not act as alias for `#symbolize_keys`.

    *Nick Weiland*

233 234 235 236
*   Improve the logic that detects non-autoloaded constants.

    *Jan Habermann*, *Xavier Noria*

237 238 239 240 241
*   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*

242 243 244 245
*   Deprecate `ActiveSupport::Multibyte::Chars.consumes?` in favor of `String#is_utf8?`.

    *Francesco Rodríguez*

246 247 248 249 250 251 252 253 254
*   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*

255 256 257 258 259
*   Deprecate `ActiveSupport::Multibyte::Unicode#normalize` and `ActiveSuppport::Multibyte::Chars#normalize`
    in favor of `String#unicode_normalize`

    *Francesco Rodríguez*

260 261 262 263 264
*   Deprecate `ActiveSupport::Multibyte::Unicode#downcase/upcase/swapcase` in favor of
    `String#downcase/upcase/swapcase`.

    *Francesco Rodríguez*

265 266 267 268
*   Add `ActiveSupport::ParameterFilter`.

    *Yoshiyuki Kinjo*

269 270 271 272 273
*   Rename `Module#parent`, `Module#parents`, and `Module#parent_name` to
    `module_parent`, `module_parents`, and `module_parent_name`.

    *Gannon McGibbon*

274 275 276 277
*   Deprecate the use of `LoggerSilence` in favor of `ActiveSupport::LoggerSilence`

    *Edouard Chin*

278 279 280 281
*   Deprecate using negative limits in `String#first` and `String#last`.

    *Gannon McGibbon*, *Eric Turner*

282 283 284 285 286
*   Fix bug where `#without` for `ActiveSupport::HashWithIndifferentAccess` would fail
    with symbol arguments

    *Abraham Chan*

287 288 289 290 291
*   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*

292 293
*   Changed `ActiveSupport::TaggedLogging.new` to return a new logger instance instead
    of mutating the one received as parameter.
294 295 296

    *Thierry Joyal*

297 298 299 300 301 302
*   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 已提交
303 304 305 306 307 308 309 310 311
*   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 已提交
312
*   Maintain `html_safe?` on html_safe strings when sliced.
313 314 315 316

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

R
Ryuta Kamizono 已提交
317
    *Elom Gomez*, *Yumin Wong*
318

B
bogdanvlviv 已提交
319 320 321 322 323 324 325 326 327 328 329
*   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*

330 331 332 333 334 335 336
*   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 已提交
337
*   Add "event object" support to the notification system.
A
Aaron Patterson 已提交
338
    Before this change, end users were forced to create hand made artisanal
A
Aaron Patterson 已提交
339 340 341 342 343
    event objects on their own, like this:

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

A
Aaron Patterson 已提交
345 346 347
        ActiveSupport::Notifications.instrument('wait') do
          sleep 1
        end
348

A
Aaron Patterson 已提交
349 350 351 352 353 354 355 356 357
        @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
358

A
Aaron Patterson 已提交
359 360 361
        ActiveSupport::Notifications.instrument('wait') do
          sleep 1
        end
362

A
Aaron Patterson 已提交
363 364 365 366 367 368 369 370
        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 已提交
371
*   Add cpu_time, idle_time, and allocations to Event.
372 373 374

    *Eileen M. Uchitelle*, *Aaron Patterson*

K
Kasper Timm Hansen 已提交
375 376 377 378 379 380 381 382 383 384
*   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 已提交
385
*   Allow `Range#===` and `Range#cover?` on Range.
U
utilum 已提交
386 387 388 389 390 391 392 393 394 395

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

396 397 398 399 400 401 402 403 404 405 406
*   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 }

407
    Closely linked with `index_by`, which creates a hash where the keys are extracted from a block.
408 409 410

    *Kasper Timm Hansen*

411
*   Fix bug where `ActiveSupport::TimeZone.all` would fail when tzinfo data for
412
    any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
413 414 415

    *Dominik Sander*

416 417 418 419 420
*   Redis cache store: `delete_matched` no longer blocks the Redis server.
    (Switches from evaled Lua to a batched SCAN + DEL loop.)

    *Gleb Mazovetskiy*

421 422 423 424 425 426 427
*   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*

428
*   Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
429 430 431 432 433 434 435

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

    *Ashe Connor*, *Aaron Patterson*

436 437 438 439 440
*   Add `before?` and `after?` methods to `Date`, `DateTime`,
    `Time`, and `TimeWithZone`.

    *Nick Holden*

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
*   `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*

469 470
*   Add `:private` option to ActiveSupport's `Module#delegate`
    in order to delegate methods as private:
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486

        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*

487 488 489 490 491
*   `String#truncate_bytes` to truncate a string to a maximum bytesize without
    breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦.

    *Jeremy Daer*

492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
*   `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 已提交
508
*   Rails 6 requires Ruby 2.5.0 or newer.
J
Jeremy Daer 已提交
509

K
Kasper Timm Hansen 已提交
510
    *Jeremy Daer*, *Kasper Timm Hansen*
J
Jeremy Daer 已提交
511

B
bogdanvlviv 已提交
512
*   Adds parallel testing to Rails.
J
Jeremy Daer 已提交
513 514 515 516

    Parallelize your test suite with forked processes or threads.

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

518

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