aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailbox/CHANGELOG.md5
-rw-r--r--actionpack/CHANGELOG.md8
-rw-r--r--actiontext/CHANGELOG.md26
-rw-r--r--activerecord/CHANGELOG.md13
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb4
-rw-r--r--activerecord/test/cases/adapters/sqlite3/collation_test.rb9
-rw-r--r--activestorage/CHANGELOG.md83
-rw-r--r--activesupport/lib/active_support/evented_file_update_checker.rb5
-rw-r--r--guides/source/6_0_release_notes.md2
-rw-r--r--guides/source/active_record_multiple_databases.md269
-rw-r--r--guides/source/configuring.md2
-rw-r--r--guides/source/documents.yaml5
-rw-r--r--guides/source/upgrading_ruby_on_rails.md8
-rw-r--r--railties/lib/rails/application/bootstrap.rb12
-rw-r--r--railties/lib/rails/application/configuration.rb12
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb3
-rw-r--r--railties/test/application/configuration_test.rb7
17 files changed, 389 insertions, 84 deletions
diff --git a/actionmailbox/CHANGELOG.md b/actionmailbox/CHANGELOG.md
index 605a38b06b..bca3d1d9ed 100644
--- a/actionmailbox/CHANGELOG.md
+++ b/actionmailbox/CHANGELOG.md
@@ -1,5 +1,6 @@
-* Add `ApplicationMailbox.mailbox_for` to expose mailbox routing.
+* Add `ApplicationMailbox.mailbox_for` to expose mailbox routing.
+
+ *James Dabbs*
- *James Dabbs*
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/actionmailbox/CHANGELOG.md) for previous changes.
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 4bcf313ecc..55592585ea 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,11 +1,11 @@
-* Keep part when scope option has value
+* Keep part when scope option has value.
When a route was defined within an optional scope, if that route didn't
take parameters the scope was lost when using path helpers. This commit
ensures scope is kept both when the route takes parameters or when it
doesn't.
- Fixes #33219
+ Fixes #33219.
*Alberto Almagro*
@@ -18,8 +18,10 @@
*Eugene Kenny*
-* Fix strong parameters blocks all attributes even when only some keys are invalid (non-numerical). It should only block invalid key's values instead.
+* Fix strong parameters blocks all attributes even when only some keys are invalid (non-numerical).
+ It should only block invalid key's values instead.
*Stan Lo*
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/actionpack/CHANGELOG.md) for previous changes.
diff --git a/actiontext/CHANGELOG.md b/actiontext/CHANGELOG.md
index 9a314db75c..d28799279f 100644
--- a/actiontext/CHANGELOG.md
+++ b/actiontext/CHANGELOG.md
@@ -1,21 +1,21 @@
-* The `fill_in_rich_text_area` system test helper locates a Trix editor and fills it in with the given HTML:
+* The `fill_in_rich_text_area` system test helper locates a Trix editor and fills it in with the given HTML:
- ```ruby
- # <trix-editor id="message_content" ...></trix-editor>
- fill_in_rich_text_area "message_content", with: "Hello <em>world!</em>"
+ ```ruby
+ # <trix-editor id="message_content" ...></trix-editor>
+ fill_in_rich_text_area "message_content", with: "Hello <em>world!</em>"
- # <trix-editor placeholder="Your message here" ...></trix-editor>
- fill_in_rich_text_area "Your message here", with: "Hello <em>world!</em>"
+ # <trix-editor placeholder="Your message here" ...></trix-editor>
+ fill_in_rich_text_area "Your message here", with: "Hello <em>world!</em>"
- # <trix-editor aria-label="Message content" ...></trix-editor>
- fill_in_rich_text_area "Message content", with: "Hello <em>world!</em>"
+ # <trix-editor aria-label="Message content" ...></trix-editor>
+ fill_in_rich_text_area "Message content", with: "Hello <em>world!</em>"
- # <input id="trix_input_1" name="message[content]" type="hidden">
- # <trix-editor input="trix_input_1"></trix-editor>
- fill_in_rich_text_area "message[content]", with: "Hello <em>world!</em>"
- ```
+ # <input id="trix_input_1" name="message[content]" type="hidden">
+ # <trix-editor input="trix_input_1"></trix-editor>
+ fill_in_rich_text_area "message[content]", with: "Hello <em>world!</em>"
+ ```
- *George Claghorn*
+ *George Claghorn*
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/actiontext/CHANGELOG.md) for previous changes.
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 6f08b1b8fe..09fdc66788 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,15 +1,20 @@
-* Fix invalid schema when primary key column has a comment
+* Fix sqlite3 collation parsing when using decimal columns.
- Fixes #29966
+ *Martin R. Schuster*
+
+* Fix invalid schema when primary key column has a comment.
+
+ Fixes #29966.
*Guilherme Goettems Schneider*
-* Fix table comment also being applied to the primary key column
+* Fix table comment also being applied to the primary key column.
*Guilherme Goettems Schneider*
* Allow generated `create_table` migrations to include or skip timestamps.
- *Michael Duchemin*
+ *Michael Duchemin*
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activerecord/CHANGELOG.md) for previous changes.
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 7f3f32162e..9fc5ee3ab4 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -477,9 +477,9 @@ module ActiveRecord
result = exec_query(sql, "SCHEMA").first
if result
- # Splitting with left parentheses and picking up last will return all
+ # Splitting with left parentheses and discarding the first part will return all
# columns separated with comma(,).
- columns_string = result["sql"].split("(").last
+ columns_string = result["sql"].split("(", 2).last
columns_string.split(",").each do |column_string|
# This regex will match the column name and collation type and will save
diff --git a/activerecord/test/cases/adapters/sqlite3/collation_test.rb b/activerecord/test/cases/adapters/sqlite3/collation_test.rb
index 76c8f7d8dd..d938b5ff2f 100644
--- a/activerecord/test/cases/adapters/sqlite3/collation_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/collation_test.rb
@@ -11,6 +11,10 @@ class SQLite3CollationTest < ActiveRecord::SQLite3TestCase
@connection.create_table :collation_table_sqlite3, force: true do |t|
t.string :string_nocase, collation: "NOCASE"
t.text :text_rtrim, collation: "RTRIM"
+ # The decimal column might interfere with collation parsing.
+ # Thus, add this column type and some other string column afterwards.
+ t.decimal :decimal_col, precision: 6, scale: 2
+ t.string :string_after_decimal_nocase, collation: "NOCASE"
end
end
@@ -22,6 +26,11 @@ class SQLite3CollationTest < ActiveRecord::SQLite3TestCase
column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == "string_nocase" }
assert_equal :string, column.type
assert_equal "NOCASE", column.collation
+
+ # Verify collation of a column behind the decimal column as well.
+ column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == "string_after_decimal_nocase" }
+ assert_equal :string, column.type
+ assert_equal "NOCASE", column.collation
end
test "text column with collation" do
diff --git a/activestorage/CHANGELOG.md b/activestorage/CHANGELOG.md
index 2d9fe56858..fdb0f143f4 100644
--- a/activestorage/CHANGELOG.md
+++ b/activestorage/CHANGELOG.md
@@ -1,59 +1,60 @@
-* Image analysis is skipped if ImageMagick returns an error.
+* Image analysis is skipped if ImageMagick returns an error.
- `ActiveStorage::Analyzer::ImageAnalyzer#metadata` would previously raise a
- `MiniMagick::Error`, which caused persistent `ActiveStorage::AnalyzeJob`
- failures. It now logs the error and returns `{}`, resulting in no metadata
- being added to the offending image blob.
+ `ActiveStorage::Analyzer::ImageAnalyzer#metadata` would previously raise a
+ `MiniMagick::Error`, which caused persistent `ActiveStorage::AnalyzeJob`
+ failures. It now logs the error and returns `{}`, resulting in no metadata
+ being added to the offending image blob.
- *George Claghorn*
+ *George Claghorn*
-* Method calls on singular attachments return `nil` when no file is attached.
+* Method calls on singular attachments return `nil` when no file is attached.
- Previously, assuming the following User model, `user.avatar.filename` would
- raise a `Module::DelegationError` if no avatar was attached:
+ Previously, assuming the following User model, `user.avatar.filename` would
+ raise a `Module::DelegationError` if no avatar was attached:
- ```ruby
- class User < ApplicationRecord
- has_one_attached :avatar
- end
- ```
+ ```ruby
+ class User < ApplicationRecord
+ has_one_attached :avatar
+ end
+ ```
- They now return `nil`.
+ They now return `nil`.
- *Matthew Tanous*
+ *Matthew Tanous*
-* The mirror service supports direct uploads.
+* The mirror service supports direct uploads.
- New files are directly uploaded to the primary service. When a
- directly-uploaded file is attached to a record, a background job is enqueued
- to copy it to each secondary service.
+ New files are directly uploaded to the primary service. When a
+ directly-uploaded file is attached to a record, a background job is enqueued
+ to copy it to each secondary service.
- Configure the queue used to process mirroring jobs by setting
- `config.active_storage.queues.mirror`. The default is `:active_storage_mirror`.
+ Configure the queue used to process mirroring jobs by setting
+ `config.active_storage.queues.mirror`. The default is `:active_storage_mirror`.
- *George Claghorn*
+ *George Claghorn*
-* The S3 service now permits uploading files larger than 5 gigabytes.
+* The S3 service now permits uploading files larger than 5 gigabytes.
- When uploading a file greater than 100 megabytes in size, the service
- transparently switches to [multipart uploads](https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html)
- using a part size computed from the file's total size and S3's part count limit.
+ When uploading a file greater than 100 megabytes in size, the service
+ transparently switches to [multipart uploads](https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html)
+ using a part size computed from the file's total size and S3's part count limit.
- No application changes are necessary to take advantage of this feature. You
- can customize the default 100 MB multipart upload threshold in your S3
- service's configuration:
+ No application changes are necessary to take advantage of this feature. You
+ can customize the default 100 MB multipart upload threshold in your S3
+ service's configuration:
- ```yaml
- production:
- service: s3
- access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
- secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
- region: us-east-1
- bucket: my-bucket
- upload:
- multipart_threshold: <%= 250.megabytes %>
- ```
+ ```yaml
+ production:
+ service: s3
+ access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
+ secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
+ region: us-east-1
+ bucket: my-bucket
+ upload:
+ multipart_threshold: <%= 250.megabytes %>
+ ```
+
+ *George Claghorn*
- *George Claghorn*
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activestorage/CHANGELOG.md) for previous changes.
diff --git a/activesupport/lib/active_support/evented_file_update_checker.rb b/activesupport/lib/active_support/evented_file_update_checker.rb
index 84caa00b58..5a79822c49 100644
--- a/activesupport/lib/active_support/evented_file_update_checker.rb
+++ b/activesupport/lib/active_support/evented_file_update_checker.rb
@@ -108,7 +108,10 @@ module ActiveSupport
private
def boot!
normalize_dirs!
- Listen.to(*@dtw, &method(:changed)).start
+
+ unless @dtw.empty?
+ Listen.to(*@dtw, &method(:changed)).start
+ end
end
def shutdown!
diff --git a/guides/source/6_0_release_notes.md b/guides/source/6_0_release_notes.md
index e421ae1ac7..c826b19f1a 100644
--- a/guides/source/6_0_release_notes.md
+++ b/guides/source/6_0_release_notes.md
@@ -686,7 +686,7 @@ Please refer to the [Changelog][active-storage] for detailed changes.
* Use the `image_processing` gem for Active Storage variants. This replaces using
`mini_magick` directly.
- ([Pull Request](https://github.com/rails/rails/pull/32471)
+ ([Pull Request](https://github.com/rails/rails/pull/32471))
* Replace existing images instead of adding to them when updating an
attached model via `update` or `update!` with, say, `@user.update!(images: [ … ])`.
diff --git a/guides/source/active_record_multiple_databases.md b/guides/source/active_record_multiple_databases.md
new file mode 100644
index 0000000000..e2c7878118
--- /dev/null
+++ b/guides/source/active_record_multiple_databases.md
@@ -0,0 +1,269 @@
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON https://guides.rubyonrails.org.**
+
+Multiple Databases with Active Record
+=====================================
+
+This guide covers using multiple databases with your Rails application.
+
+After reading this guide you will know:
+
+* How to setup your application for multiple databases.
+* How automatic connection switching works.
+* What features are supported and what's still a work in progress.
+
+--------------------------------------------------------------------------------
+
+As an application grows in popularity and usage you'll need to scale the application
+to support your new users and their data. One way in which your application may need
+to scale is on the database level. Rails now has support for multiple databases
+so you don't have to store your data all in one place.
+
+At this time the following features are supported:
+
+* Multiple primary databases and a replica for each
+* Automatic connection switching for the model you're working with
+* Automatic swapping between the primary and replica depending on the HTTP verb
+and recent writes
+* Rails tasks for creating, dropping, migrating, and interacting with the multiple
+databases
+
+The following features are not (yet) supported:
+
+* Sharding
+* Joining across clusters
+* Load balancing replicas
+
+## Setting up your application
+
+While Rails tries to do most of the work for you there are still some steps you'll
+need to do to get your application ready for multiple databases.
+
+Let's say we have an application with a single primary database and we need to add a
+new database for some new tables we're adding. The name of the new database will be
+"animals".
+
+The database.yml looks like this:
+
+```yaml
+production:
+ database: my_primary_database
+ user: root
+ adapter: mysql
+```
+
+Let's add a replica for the primary, a new writer called animals and a replica for that
+as well. To do this we need to change our database.yml from a 2-tier to a 3-tier config.
+
+```yaml
+production:
+ primary:
+ database: my_primary_database
+ user: root
+ adapter: mysql
+ primary_replica:
+ database: my_primary_database
+ user: root_readonly
+ adapter: mysql
+ replica: true
+ animals:
+ database: my_animals_database
+ user: animals_root
+ adapter: mysql
+ migrations_paths: db/animals_migrate
+ animals_replica:
+ database: my_animals_database
+ user: animals_readonly
+ adapter: mysql
+ replica: true
+```
+
+When using multiple databases there are a few important settings.
+
+First, the database name for the primary and replica should be the same because they contain
+the same data. Second, the username for the primary and replica should be different, and the
+replica user's permissions should be to read and not write.
+
+When using a replica database you need to add a `replica: true` entry to the replica in the
+`database.yml`. This is because Rails otherwise has no way of knowing which one is a replica
+and which one is the primary.
+
+Lastly, for new primary databases you need to set the `migrations_paths` to the directory
+where you will store migrations for that database. We'll look more at `migrations_paths`
+later on in this guide.
+
+Now that we have a new database, let's set up the model. In order to use the new database we
+need to create a new abstract class and connect to the animals databases.
+
+```ruby
+class AnimalsBase < ApplicationRecord
+ self.abstract_class = true
+
+ connects_to database: { writing: :animals, reading: :animals_replica }
+end
+```
+ Then we need to
+update `ApplicationRecord` to be aware of our new replica.
+
+```ruby
+class ApplicationRecord < ActiveRecord::Base
+ self.abstract_class = true
+
+ connects_to database: { writing: :primary, reading: :primary_replica }
+end
+```
+
+By default Rails expects the database roles to be `writing` and `reading` for the primary
+and replica respectively. If you have a legacy system you may already have roles set up that
+you don't want to change. In that case you can set a new role name in your application config.
+
+```ruby
+config.active_record.writing_role = :default
+config.active_record.reading_role = :readonly
+```
+
+Now that we have the database.yml and the new model set up it's time to create the databases.
+Rails 6.0 ships with all the rails tasks you need to use multiple databases in Rails.
+
+You can run `rails -T` to see all the commands you're able to run. You should see the following:
+
+```
+$ rails -T
+rails db:create # Creates the database from DATABASE_URL or config/database.yml for the ...
+rails db:create:animals # Create animals database for current environment
+rails db:create:primary # Create primary database for current environment
+rails db:drop # Drops the database from DATABASE_URL or config/database.yml for the cu...
+rails db:drop:animals # Drop animals database for current environment
+rails db:drop:primary # Drop primary database for current environment
+rails db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)
+rails db:migrate:animals # Migrate animals database for current environment
+rails db:migrate:primary # Migrate primary database for current environment
+rails db:migrate:status # Display status of migrations
+rails db:migrate:status:animals # Display status of migrations for animals database
+rails db:migrate:status:primary # Display status of migrations for primary database
+```
+
+Running a command like `rails db:create` will create both the primary and animals databases.
+Note that there is no command for creating the users and you'll need to do that manually
+to support the readonly users for your replicas. If you want to create just the animals
+database you can run `rails db:create:animals`.
+
+## Migrations
+
+Migrations for multiple databases should live in their own folders prefixed with the
+name of the database key in the configuration.
+
+You also need to set the `migrations_paths` in the database configurations to tell Rails
+where to find the migrations.
+
+For example the `animals` database would look in the `db/animals_migrate` directory and
+`primary` would look in `db/migrate`. Rails generators now take a `--database` option
+so that the file is generated in the correct directory. The command can be run like so:
+
+```
+$ rails g migration CreateDogs name:string --database animals
+```
+
+## Activating automatic connection switching
+
+Finally, in order to use the read-only replica in your application you'll need to activate
+the middleware for automatic switching.
+
+Automatic switching allows the application to switch from the primary to replica or replica
+to primary based on the HTTP verb and whether there was a recent write.
+
+If the application is receiving a POST, PUT, DELETE, or PATCH request the application will
+automatically write to the primary. For the specified time after the write the application
+will read from the replica. For a GET or HEAD request the application will read from the
+replica unless there was a recent write.
+
+To activate the automatic connection switching middleware, add or uncomment the following
+lines in your application config.
+
+```ruby
+config.active_record.database_selector = { delay: 2.seconds }
+config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
+config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
+```
+
+Rails guarantees "read your own write" and will send your GET or HEAD request to the
+primary if it's within the `delay` window. By default the delay is set to 2 seconds. You
+should change this based on your database infrastructure. Rails doesn't guarantee "read
+a recent write" for other users within the delay window and will send GET and HEAD requests
+to the replicas unless they wrote recently.
+
+The automatic connection switching in Rails is relatively primitive and deliberatly doesn't
+do a whole lot. The goal was a system that demonstrated how to do automatic connection
+switching that was flexible enough to be customizable by app developers.
+
+The setup in Rails allows you to easily change how the switching is done and what
+parameters it's based on. Let's say you want to use a cookie instead of a session to
+decide when to swap connections. You can write your own class:
+
+```ruby
+class MyCookieResolver
+ # code for your cookie class
+end
+```
+
+And then pass it to the middleware:
+
+```ruby
+config.active_record.database_selector = { delay: 2.seconds }
+config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
+config.active_record.database_resolver_context = MyCookieResovler
+```
+
+## Using manual connection switching
+
+There are some cases where you may want your application to connect to a primary or a replica
+and the automatic connection switching isn't adequate. For example, you may know that for a
+particular request you always want to send the request to a replica, even when you are in a
+POST request path.
+
+To do this Rails provides a `connected_to` method that will switch to the connection you
+need.
+
+```ruby
+ActiveRecord::Base.connected_to(role: :reading) do
+ # all code in this block will be connected to the reading role
+end
+```
+
+The "role" in the `connected_to` call looks up the connections that are connected on that
+connection handler (or role). The `reading` connection handler will hold all the connections
+that were connected via `connects_to` with the role name of `reading`.
+
+There also may be a case where you have a database that you don't always want to connect to
+on application boot but may need for a slow query or analytics. After defining that database
+in the database.yml you can connect by passing a database argument to `connected_to`
+
+```ruby
+ActiveRecord::Base.connected_to(database: { reading_slow: :animals_slow_replica }) do
+ # do something while connected to the slow replica
+end
+```
+
+The `database` argument for `connected_to` will take a symbol or a config hash.
+
+Note that `connected_to` with a role will look up an existing connection and switch
+using the connection specification name. This means that if you pass an unknown role
+like `connected_to(role: :nonexistent)` you will get an error like that says
+`ActiveRecord::ConnectionNotEstablished (No connection pool with 'AnimalsBase' found
+for the 'nonexistent' role.)`
+
+## Caveats
+
+As noted at the top Rails doesn't (yet) support sharding. We had to do a lot of work
+to support multiple databases for Rails 6.0. The lack of support for sharding isn't
+an oversight, but does require additional work that didn't make it in for 6.0. For now
+if you need sharding it may be advisable to continue using one of the many gems
+that supports this.
+
+Rails also doesn't support automatic load balancing of replicas. This is very
+dependent on your infrastructure. We may implement basic, primitive load balancing
+in the future, but for an application at scale this should be something your application
+handles outside of Rails.
+
+Lastly, you cannot join across databases. Rails 6.1 will support using `has_many`
+relationships and creating 2 queries instead of joining, but Rails 6.0 will require
+you to split the joins into 2 selects manually.
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index cc64c7eac6..4651290674 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -897,7 +897,7 @@ text/javascript image/svg+xml application/postscript application/x-shockwave-fla
#### With '5.2':
- `config.active_record.cache_versioning`: `true`
-- `action_dispatch.use_authenticated_cookie_encryption`: `true`
+- `config.action_dispatch.use_authenticated_cookie_encryption`: `true`
- `config.active_support.use_authenticated_message_encryption`: `true`
- `config.active_support.use_sha1_digests`: `true`
- `config.action_controller.default_protect_from_forgery`: `true`
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 1e67b2bce7..90674e8456 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -160,6 +160,11 @@
work_in_progress: true
url: active_record_postgresql.html
description: This guide covers PostgreSQL specific usage of Active Record.
+ -
+ name: Multiple Databases with Active Record
+ work_in_progress: true
+ url: active_record_multiple_databases.html
+ description: This guide covers using multiple databases in your application.
-
name: Extending Rails
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 1110592d5e..54f014293d 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -134,12 +134,12 @@ Action Cable JavaScript API:
+ ActionCable.logger.enabled = false
```
-### `ActionDispatch::Response#content_type` now returned Content-Type header as it is.
+### `ActionDispatch::Response#content_type` now returns the Content-Type header without modification
-Previously, `ActionDispatch::Response#content_type` returned value does NOT contain charset part.
-This behavior changed to returned Content-Type header containing charset part as it is.
+Previously, the return value of `ActionDispatch::Response#content_type` did NOT contain the charset part.
+This behavior has changed to include the previously omitted charset part as well.
-If you want just MIME type, please use `ActionDispatch::Response#media_type` instead.
+If you want just the MIME type, please use `ActionDispatch::Response#media_type` instead.
Before:
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
index 50685a4d7a..1fdc7b2d71 100644
--- a/railties/lib/rails/application/bootstrap.rb
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -34,20 +34,12 @@ module Rails
# Initialize the logger early in the stack in case we need to log some deprecation.
initializer :initialize_logger, group: :all do
Rails.logger ||= config.logger || begin
- path = config.paths["log"].first
- unless File.exist? File.dirname path
- FileUtils.mkdir_p File.dirname path
- end
-
- f = File.open path, "a"
- f.binmode
- f.sync = config.autoflush_log # if true make sure every write flushes
-
- logger = ActiveSupport::Logger.new f
+ logger = ActiveSupport::Logger.new(config.default_log_file)
logger.formatter = config.log_formatter
logger = ActiveSupport::TaggedLogging.new(logger)
logger
rescue StandardError
+ path = config.paths["log"].first
logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDERR))
logger.level = ActiveSupport::Logger::WARN
logger.warn(
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 0b758dd3dd..da1c433e52 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -311,6 +311,18 @@ module Rails
end
end
+ def default_log_file
+ path = paths["log"].first
+ unless File.exist? File.dirname path
+ FileUtils.mkdir_p File.dirname path
+ end
+
+ f = File.open path, "a"
+ f.binmode
+ f.sync = autoflush_log # if true make sure every write flushes
+ f
+ end
+
class Custom #:nodoc:
def initialize
@configurations = Hash.new
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 7336e235f6..578881d1ac 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -244,7 +244,6 @@ module Rails
RAILS_DEV_PATH = File.expand_path("../../../../../..", __dir__)
class AppGenerator < AppBase
-
# :stopdoc:
WEBPACKS = %w( react vue angular elm stimulus )
@@ -495,7 +494,7 @@ module Rails
"rails new #{arguments.map(&:usage).join(' ')} [options]"
end
- # :startdoc:
+ # :startdoc:
private
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 7c613585e0..6f9711cb37 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -1607,6 +1607,13 @@ module ApplicationTests
assert_not_nil Rails::SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/]
end
+ test "config.default_log_file returns a File instance" do
+ app "development"
+
+ assert_instance_of File, app.config.default_log_file
+ assert_equal Rails.application.config.paths["log"].first, app.config.default_log_file.path
+ end
+
test "rake_tasks block works at instance level" do
app_file "config/environments/development.rb", <<-RUBY
Rails.application.configure do