diff options
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/5_1_release_notes.md | 4 | ||||
-rw-r--r-- | guides/source/6_0_release_notes.md | 26 | ||||
-rw-r--r-- | guides/source/active_record_migrations.md | 2 | ||||
-rw-r--r-- | guides/source/active_support_instrumentation.md | 11 | ||||
-rw-r--r-- | guides/source/configuring.md | 10 | ||||
-rw-r--r-- | guides/source/contributing_to_ruby_on_rails.md | 2 | ||||
-rw-r--r-- | guides/source/getting_started.md | 2 | ||||
-rw-r--r-- | guides/source/testing.md | 2 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 255 |
9 files changed, 290 insertions, 24 deletions
diff --git a/guides/source/5_1_release_notes.md b/guides/source/5_1_release_notes.md index e885b1e42e..f870c4c47c 100644 --- a/guides/source/5_1_release_notes.md +++ b/guides/source/5_1_release_notes.md @@ -41,8 +41,8 @@ Major Features [Pull Request](https://github.com/rails/rails/pull/26836) Rails 5.1 allows managing JavaScript dependencies -from NPM via Yarn. This will make it easy to use libraries like React, VueJS -or any other library from NPM world. The Yarn support is integrated with +from npm via Yarn. This will make it easy to use libraries like React, VueJS +or any other library from npm world. The Yarn support is integrated with the asset pipeline so that all dependencies will work seamlessly with the Rails 5.1 app. diff --git a/guides/source/6_0_release_notes.md b/guides/source/6_0_release_notes.md index 4eb5296c41..fa45e7240d 100644 --- a/guides/source/6_0_release_notes.md +++ b/guides/source/6_0_release_notes.md @@ -178,7 +178,7 @@ Please refer to the [Changelog][action-cable] for detailed changes. `ActionCable::Connection`. ([Pull Request](https://github.com/rails/rails/pull/34194)) -* Convert the Action Cable Javascript package from CoffeeScript to ES2015 and +* Convert the Action Cable JavaScript package from CoffeeScript to ES2015 and publish the source code in the npm distribution. ([Pull Request](https://github.com/rails/rails/pull/34370)) @@ -202,7 +202,7 @@ Please refer to the [Changelog][action-pack] for detailed changes. * Remove deprecated methods in `ActionDispatch::TestResponse`: `#success?` in favor of `#successful?`, `#missing?` in favor of `#not_found?`, - `#error?` in favor of `#server_error?` + `#error?` in favor of `#server_error?`. ([Commit](https://github.com/rails/rails/commit/13ddc92e079e59a0b894e31bf5bb4fdecbd235d1)) ### Deprecations @@ -229,7 +229,7 @@ Please refer to the [Changelog][action-pack] for detailed changes. * Allow the use of `parsed_body` in `ActionController::TestCase`. ([Pull Request](https://github.com/rails/rails/pull/34717)) -* Raise an `ArgumentError` when multiple root routes exists in the same context +* Raise an `ArgumentError` when multiple root routes exist in the same context without `as:` naming specifications. ([Pull Request](https://github.com/rails/rails/pull/34494)) @@ -245,7 +245,7 @@ Please refer to the [Changelog][action-pack] for detailed changes. * Expose `ActionController::Parameters#each_key`. ([Pull Request](https://github.com/rails/rails/pull/33758)) -* Add purpose metadata to signed/encrypted cookies to prevent copying the value of +* Add purpose and expiry metadata inside signed/encrypted cookies to prevent copying the value of cookies into one another. ([Pull Request](https://github.com/rails/rails/pull/32937)) @@ -298,14 +298,14 @@ Please refer to the [Changelog][action-view] for detailed changes. ### Notable changes -* Clear ActionView cache in development only on file changes, speeding up +* Clear Action View cache in development only on file changes, speeding up development mode. ([Pull Request](https://github.com/rails/rails/pull/35629)) * Move all of the Rails npm packages into a `@rails` scope. ([Pull Request](https://github.com/rails/rails/pull/34905)) -* Only accept formats from registered Mime types. +* Only accept formats from registered MIME types. ([Pull Request](https://github.com/rails/rails/pull/35604), [Pull Request](https://github.com/rails/rails/pull/35753)) * Add allocations to the template and partial rendering server output. @@ -323,7 +323,7 @@ Please refer to the [Changelog][action-view] for detailed changes. enable `ActionView::Template` finalizers. ([Pull Request](https://github.com/rails/rails/pull/32418)) -* Extract the JS `confirm` call to its own, overridable method in `rails_ujs`. +* Extract the JavaScript `confirm` call to its own, overridable method in `rails_ujs`. ([Pull Request](https://github.com/rails/rails/pull/32404)) * Add a `action_controller.default_enforce_utf8` configuration option to handle @@ -402,7 +402,7 @@ Please refer to the [Changelog][active-record] for detailed changes. * Remove support for passing the column name to `count` when a block is passed. ([Commit](https://github.com/rails/rails/commit/67356f2034ab41305af7218f7c8b2fee2d614129)) -* Remove support for delegation of missing methods in a relation to arel. +* Remove support for delegation of missing methods in a relation to Arel. ([Commit](https://github.com/rails/rails/commit/d97980a16d76ad190042b4d8578109714e9c53d0)) * Remove support for delegating missing methods in a relation to private methods of the class. @@ -445,7 +445,7 @@ Please refer to the [Changelog][active-record] for detailed changes. ### Notable changes -* Bump the minimum sqlite3 version to 1.4. +* Bump the minimum version of the `sqlite3` gem to 1.4. ([Pull Request](https://github.com/rails/rails/pull/35844)) * Add `rails db:prepare` to create a database if it doesn't exist, and run its migrations. @@ -467,7 +467,7 @@ Please refer to the [Changelog][active-record] for detailed changes. ([Pull Request](https://github.com/rails/rails/pull/35631)) * Add `rails db:seed:replant` that truncates tables of each database - for ther current environment and loads the seeds. + for the current environment and loads the seeds. ([Pull Request](https://github.com/rails/rails/pull/34779)) * Add `reselect` method, which is a short-hand for `unscope(:select).select(fields)`. @@ -577,7 +577,7 @@ Please refer to the [Changelog][active-record] for detailed changes. * Allow the `:to_table` option of `remove_foreign_key` to be invertible. ([Pull Request](https://github.com/rails/rails/pull/33530)) -* Fix default value for mysql time types with specified precision. +* Fix default value for MySQL time types with specified precision. ([Pull Request](https://github.com/rails/rails/pull/33280)) * Fix the `touch` option to behave consistently with `Persistence#touch` method. @@ -762,7 +762,7 @@ Please refer to the [Changelog][active-support] for detailed changes. ([Pull Request](https://github.com/rails/rails/pull/34123)) * Deprecate `ActiveSupport::Multibyte::Unicode#normalize` - and `ActiveSuppport::Multibyte::Chars#normalize` in favor of + and `ActiveSupport::Multibyte::Chars#normalize` in favor of `String#unicode_normalize`. ([Pull Request](https://github.com/rails/rails/pull/34202)) @@ -771,7 +771,7 @@ Please refer to the [Changelog][active-support] for detailed changes. ([Pull Request](https://github.com/rails/rails/pull/34215)) * Deprecate `ActiveSupport::Multibyte::Unicode#pack_graphemes(array)` - and `ActiveSuppport::Multibyte::Unicode#unpack_graphemes(string)` + and `ActiveSupport::Multibyte::Unicode#unpack_graphemes(string)` in favor of `array.flatten.pack("U*")` and `string.scan(/\X/).map(&:codepoints)`, respectively. ([Pull Request](https://github.com/rails/rails/pull/34254)) diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md index 270e4a3bf9..9398244ccf 100644 --- a/guides/source/active_record_migrations.md +++ b/guides/source/active_record_migrations.md @@ -225,6 +225,8 @@ class CreateProducts < ActiveRecord::Migration[5.0] create_table :products do |t| t.string :name t.string :part_number + + t.timestamps end end end diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md index 4868b00bbe..9f15e70da6 100644 --- a/guides/source/active_support_instrumentation.md +++ b/guides/source/active_support_instrumentation.md @@ -643,7 +643,16 @@ The block receives the following arguments: ```ruby ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, data| # your own custom stuff - Rails.logger.info "#{name} Received!" + Rails.logger.info "#{name} Received! (started: #{started}, finished: #{finished})" # process_action.action_controller Received (started: 2019-05-05 13:43:57 -0800, finished: 2019-05-05 13:43:58 -0800) +end +``` + +If you are concerned about the accuracy of `started` and `finished` to compute a precise elapsed time then use `ActiveSupport::Notifications.monotonic_subscribe`. The given block would receive the same arguments as above but the `started` and `finished` will have values with an accurate monotonic time instead of wall-clock time. + +```ruby +ActiveSupport::Notifications.monotonic_subscribe "process_action.action_controller" do |name, started, finished, unique_id, data| + # your own custom stuff + Rails.logger.info "#{name} Received! (started: #{started}, finished: #{finished})" # process_action.action_controller Received (started: 1560978.425334, finished: 1560979.429234) end ``` diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 2ee65bb573..00f43777a8 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -145,7 +145,7 @@ defaults to `:debug` for all environments. The available log levels are: `:debug * `secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get a random generated key in test and development environments, other environments should set one in `config/credentials.yml.enc`. -* `config.public_file_server.enabled` configures Rails to serve static files from the public directory. This option defaults to `true`, but in the production environment it is set to `false` because the server software (e.g. NGINX or Apache) used to run the application should serve static files instead. If you are running or testing your app in production mode using WEBrick (it is not recommended to use WEBrick in production) set the option to `true.` Otherwise, you won't be able to use page caching and request for files that exist under the public directory. +* `config.public_file_server.enabled` configures Rails to serve static files from the public directory. This option defaults to `true`, but in the production environment it is set to `false` because the server software (e.g. NGINX or Apache) used to run the application should serve static files instead. If you are running or testing your app in production mode using WEBrick (it is not recommended to use WEBrick in production) set the option to `true`. Otherwise, you won't be able to use page caching and request for files that exist under the public directory. * `config.session_store` specifies what class to use to store the session. Possible values are `:cookie_store` which is the default, `:mem_cache_store`, and `:disabled`. The last one tells Rails not to deal with sessions. Defaults to a cookie store with application name as the session key. Custom session stores can also be specified: @@ -389,6 +389,12 @@ All these configuration options are delegated to the `I18n` library. having to send a query to the database to get this information. Defaults to `true`. +* `config.active_record.collection_cache_versioning` enables the same cache key + to be reused when the object being cached of type `ActiveRecord::Relation` + changes by moving the volatile information (max updated at and count) of + the relation's cache key into the cache version to support recycling cache key. + Defaults to `false`. + The MySQL adapter adds one additional configuration option: * `ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans` controls whether Active Record will consider all `tinyint(1)` columns as booleans. Defaults to `true`. @@ -892,12 +898,14 @@ text/javascript image/svg+xml application/postscript application/x-shockwave-fla #### With '6.0': +- `config.autoloader`: `:zeitwerk` - `config.action_view.default_enforce_utf8`: `false` - `config.action_dispatch.use_cookies_with_metadata`: `true` - `config.action_mailer.delivery_job`: `"ActionMailer::MailDeliveryJob"` - `config.active_job.return_false_on_aborted_enqueue`: `true` - `config.active_storage.queues.analysis`: `:active_storage_analysis` - `config.active_storage.queues.purge`: `:active_storage_purge` +- `config.active_record.collection_cache_versioning`: `true` ### Configuring a Database diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md index f86589bdf1..a6eb9907a0 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -340,7 +340,7 @@ $ TEST_DIR=generators bundle exec rake test You can run the tests for a particular file by using: ```bash -$ cd actionpack +$ cd actionview $ bundle exec ruby -w -Itest test/template/form_helper_test.rb ``` diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 7000fa408c..e8b224a1a3 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -207,7 +207,7 @@ folder directly to the Ruby interpreter e.g. `ruby bin\rails server`. TIP: JavaScript asset compression requires you have a JavaScript runtime available on your system, in the absence -of a runtime you will see an `execjs` error during asset compilation. +of a runtime you will see an `execjs` error during asset compression. Usually macOS and Windows come with a JavaScript runtime installed. `therubyrhino` is the recommended runtime for JRuby users and is added by default to the `Gemfile` in apps generated under JRuby. You can investigate diff --git a/guides/source/testing.md b/guides/source/testing.md index 18eecf49fa..9540bb2af5 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -781,7 +781,7 @@ This can be helpful for viewing the browser at the point a test failed, or to view screenshots later for debugging. Two methods are provided: `take_screenshot` and `take_failed_screenshot`. -`take_failed_screenshot` is automatically included in `after_teardown` inside +`take_failed_screenshot` is automatically included in `before_teardown` inside Rails. The `take_screenshot` helper method can be included anywhere in your tests to diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 7e4152aa51..b8a5c39f39 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -85,13 +85,14 @@ Rails 6.1. You are encouraged to enable `config.force_ssl` to enforce HTTPS connections throughout your application. If you need to exempt certain endpoints from redirection, you can use `config.ssl_options` to configure that behavior. -### Purpose in signed or encrypted cookie is now embedded within cookies +### Purpose and expiry metadata is now embedded inside signed and encrypted cookies for increased security + +To improve security, Rails embeds the purpose and expiry metadata inside encrypted or signed cookies value. -To improve security, Rails embeds the purpose information in encrypted or signed cookies value. Rails can then thwart attacks that attempt to copy the signed/encrypted value of a cookie and use it as the value of another cookie. -This new embed information make those cookies incompatible with versions of Rails older than 6.0. +This new embed metadata make those cookies incompatible with versions of Rails older than 6.0. If you require your cookies to be read by Rails 5.2 and older, or you are still validating your 6.0 deploy and want to be able to rollback set @@ -133,6 +134,252 @@ Action Cable JavaScript API: + ActionCable.logger.enabled = false ``` +### Autoloading + +The default configuration for Rails 6 + +```ruby +# config/application.rb + +config.load_defaults "6.0" +``` + +enables `zeitwerk` autoloading mode on CRuby. In that mode, autoloading, reloading, and eager loading are managed by [Zeitwerk](https://github.com/fxn/zeitwerk). + +#### Public API + +In general, applications do not need to use the API of Zeitwerk directly. Rails sets things up according to the existing contract: `config.autoload_paths`, `config.cache_classes`, etc. + +While applications should stick to that interface, the actual Zeitwerk loader object can be accessed as + +```ruby +Rails.autoloaders.main +``` + +That may be handy if you need to preload STIs or configure a custom inflector, for example. + +#### Project Structure + +If the application being upgraded autoloads correctly, the project structure should be already mostly compatible. + +However, `classic` mode infers file names from missing constant names (`underscore`), whereas `zeitwerk` mode infers constant names from file names (`camelize`). These helpers are not always inverse of each other, in particular if acronyms are involved. For instance, `"FOO".underscore` is `"foo"`, but `"foo".camelize` is `"Foo"`, not `"FOO"`. Compatibility can be checked by setting `classic` mode first temporarily: + +```ruby +# config/application.rb + +config.load_defaults "6.0" +config.autoloader = :classic +``` + +and then running + +``` +bin/rails zeitwerk:check +``` + +When all is good, you can delete `config.autoloader = :classic`. + +#### require_dependency + +All known use cases of `require_dependency` have been eliminated, you should grep the project and delete them. + +In the case of STIs with a hierarchy of more than two levels, you can preload the leaves of the hierarchy in an initializer: + +```ruby +# config/initializers/preload_stis.rb + +# By preloading leaves, the hierarchy is loaded upwards following +# the references to superclasses in the class definitions. +sti_leaves = %w( + app/models/leaf1.rb + app/models/leaf2.rb + app/models/leaf3.rb +) +Rails.autoloaders.main.preload(sti_leaves) +``` + +#### Qualified names in class and module definitions + +You can now robustly use constant paths in class and module definitions: + +```ruby +# Autoloading in this class' body matches Ruby semantics now. +class Admin::UsersController < ApplicationController + # ... +end +``` + +A gotcha to be aware of is that, depending on the order of execution, the classic autoloader could sometimes be able to autoload `Foo::Wadus` in + +```ruby +class Foo::Bar + Wadus +end +``` + +That does not match Ruby semantics because `Foo` is not in the nesting, and won't work at all in `zeitwerk` mode. If you find such corner case you can use the qualified name `Foo::Wadus`: + +```ruby +class Foo::Bar + Foo::Wadus +end +``` + +or add `Foo` to the nesting: + +```ruby +module Foo + class Bar + Wadus + end +end +``` + +#### Concerns + +You can autoload and eager load from a standard structure like + +``` +app/models +app/models/concerns +``` + +In that case, `app/models/concerns` is assumed to be a root directory (because it belongs to the autoload paths), and it is ignored as namespace. So, `app/models/concerns/foo.rb` should define `Foo`, not `Concerns::Foo`. + +The `Concerns::` namespace worked with the classic autoloader as a side-effect of the implementation, but it was not really an intended behavior. An application using `Concerns::` needs to rename those classes and modules to be able to run in `zeitwerk` mode. + +#### Autoloaded Constants and Explicit Namespaces + +If a namespace is defined in a file, as `Hotel` is here: + +``` +app/models/hotel.rb # Defines Hotel. +app/models/hotel/pricing.rb # Defines Hotel::Pricing. +``` + +the `Hotel` constant has to be set using the `class` or `module` keywords. For example: + +```ruby +class Hotel +end +``` + +is good. + +Alternatives like + +```ruby +Hotel = Class.new +``` + +or + +```ruby +Hotel = Struct.new +``` + +won't work, child objects like `Hotel::Pricing` won't be found. + +This restriction only applies to explicit namespaces. Classes and modules not defining a namespace can be defined using those idioms. + +#### One file, one constant (at the same top-level) + +In `classic` mode you could technically define several constants at the same top-level and have them all reloaded. For example, given + +```ruby +# app/models/foo.rb + +class Foo +end + +class Bar +end +``` + +while `Bar` could not be autoloaded, autoloading `Foo` would mark `Bar` as autoloaded too. This is not the case in `zeitwerk` mode, you need to move `Bar` to its own file `bar.rb`. One file, one constant. + +This affects only to constants at the same top-level as in the example above. Inner classes and modules are fine. For example, consider + +```ruby +# app/models/foo.rb + +class Foo + class InnerClass + end +end +``` + +If the application reloads `Foo`, it will reload `Foo::InnerClass` too. + +#### Spring and the `test` Environment + +Spring reloads the application code if something changes. In the `test` environment you need to enable reloading for that to work: + +```ruby +# config/environments/test.rb + +config.cache_classes = false +``` + +Otherwise you'll get this error: + +``` +reloading is disabled because config.cache_classes is true +``` + +#### Bootsnap + +Bootsnap should be at least version 1.4.2. + +In addition to that, Bootsnap needs to disable the iseq cache due to a bug in the interpreter if running Ruby 2.5. Please make sure to depend on at least Bootsnap 1.4.4 in that case. + +#### `config.add_autoload_paths_to_load_path` + +The new configuration point + +```ruby +config.add_autoload_paths_to_load_path +``` + +is `true` by default for backwards compatibility, but allows you to opt-out from adding the autoload paths to `$LOAD_PATH`. + +This makes sense in most applications, since you never should require a file in `app/models`, for example, and Zeitwerk only uses absolute file names internally. + +By opting-out you optimize `$LOAD_PATH` lookups (less directories to check), and save Bootsnap work and memory consumption, since it does not need to build an index for these directories. + +#### Thread-safety + +In classic mode, constant autoloading is not thread-safe, though Rails has locks in place for example to make web requests thread-safe when autoloading is enabled, as it is common in `development` mode. + +Constant autoloading is thread-safe in `zeitwerk` mode. For example, you can now autoload in multi-threaded scripts executed by the `runner` command. + +#### Globs in config.autoload_paths + +Beware of configurations like + +```ruby +config.autoload_paths += Dir["#{config.root}/lib/**/"] +``` + +Every element of `config.autoload_paths` should represent the top-level namespace (`Object`) and they cannot be nested in consequence (with the exception of `concerns` directories explained above). + +To fix this, just remove the wildcards: + +```ruby +config.autoload_paths << "#{config.root}/lib" +``` + +#### How to Use the Classic Autoloader in Rails 6 + +Applications can load Rails 6 defaults and still use the classic autoloader by setting `config.autoloader` this way: + +```ruby +# config/application.rb + +config.load_defaults "6.0" +config.autoloader = :classic +``` + Upgrading from Rails 5.1 to Rails 5.2 ------------------------------------- @@ -1557,7 +1804,7 @@ config.assets.enabled = true config.assets.version = '1.0' ``` -If your application is using an "/assets" route for a resource you may want change the prefix used for assets to avoid conflicts: +If your application is using an "/assets" route for a resource you may want to change the prefix used for assets to avoid conflicts: ```ruby # Defaults to '/assets' |