diff options
Diffstat (limited to 'guides/source')
-rw-r--r-- | guides/source/6_0_release_notes.md | 9 | ||||
-rw-r--r-- | guides/source/action_mailbox_basics.md | 302 | ||||
-rw-r--r-- | guides/source/action_mailer_basics.md | 52 | ||||
-rw-r--r-- | guides/source/active_record_migrations.md | 13 | ||||
-rw-r--r-- | guides/source/active_support_core_extensions.md | 87 | ||||
-rw-r--r-- | guides/source/active_support_instrumentation.md | 40 | ||||
-rw-r--r-- | guides/source/asset_pipeline.md | 4 | ||||
-rw-r--r-- | guides/source/configuring.md | 4 | ||||
-rw-r--r-- | guides/source/documents.yaml | 7 | ||||
-rw-r--r-- | guides/source/getting_started.md | 2 | ||||
-rw-r--r-- | guides/source/testing.md | 8 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 2 |
12 files changed, 357 insertions, 173 deletions
diff --git a/guides/source/6_0_release_notes.md b/guides/source/6_0_release_notes.md index f3ed21dc45..9716132156 100644 --- a/guides/source/6_0_release_notes.md +++ b/guides/source/6_0_release_notes.md @@ -5,6 +5,7 @@ Ruby on Rails 6.0 Release Notes Highlights in Rails 6.0: +* Action Mailbox * Parallel Testing These release notes cover only the major changes. To learn about various bug @@ -28,6 +29,14 @@ guide. Major Features -------------- +### Action Mailbox + +[Pull Request](https://github.com/rails/rails/pull/34786) + +[Action Mailbox](https://github.com/rails/rails/tree/6-0-stable/actionmailbox) allows you +to route incoming emails to controller-like mailboxes. +You can read more about Action Mailbox in the [Action Mailbox Basics](action_mailbox_basics.html) guide. + ### Parallel Testing [Pull Request](https://github.com/rails/rails/pull/31900) diff --git a/guides/source/action_mailbox_basics.md b/guides/source/action_mailbox_basics.md new file mode 100644 index 0000000000..87000bf5cf --- /dev/null +++ b/guides/source/action_mailbox_basics.md @@ -0,0 +1,302 @@ +**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON https://guides.rubyonrails.org.** + +Action Mailbox Basics +===================== + +This guide provides you with all you need to get started in receiving +emails to your application. + +After reading this guide, you will know: + +* How to receive email within a Rails application. +* How to configure Action Mailbox. +* How to generate and route emails to a mailbox. +* How to test incoming emails. + +-------------------------------------------------------------------------------- + +Introduction +------------ + +Action Mailbox routes incoming emails to controller-like mailboxes for +processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill, +and SendGrid. You can also handle inbound mails directly via the built-in +Postfix ingress. + +The inbound emails are turned into `InboundEmail` records using Active Record +and feature lifecycle tracking, storage of the original email on cloud storage +via Active Storage, and responsible data handling with +on-by-default incineration. + +These inbound emails are routed asynchronously using Active Job to one or +several dedicated mailboxes, which are capable of interacting directly +with the rest of your domain model. + +## Setup + +Install migrations needed for `InboundEmail` and ensure Active Storage is set up: + +```bash +$ rails action_mailbox:install +$ rails db:migrate +``` + +## Configuration + +### Amazon SES + +Install the [`aws-sdk-sns`](https://rubygems.org/gems/aws-sdk-sns) gem: + +```ruby +# Gemfile +gem "aws-sdk-sns", ">= 1.9.0", require: false + ``` + +Tell Action Mailbox to accept emails from SES: + +```ruby +# config/environments/production.rb +config.action_mailbox.ingress = :amazon +``` + +[Configure SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-notifications.html) +to deliver emails to your application via POST requests to +`/rails/action_mailbox/amazon/inbound_emails`. If your application lived at +`https://example.com`, you would specify the fully-qualified URL +`https://example.com/rails/action_mailbox/amazon/inbound_emails`. + +### Mailgun + +Give Action Mailbox your +[Mailgun API key](https://help.mailgun.com/hc/en-us/articles/203380100-Where-can-I-find-my-API-key-and-SMTP-credentials) +so it can authenticate requests to the Mailgun ingress. + +Use `rails credentials:edit` to add your API key to your application's +encrypted credentials under `action_mailbox.mailgun_api_key`, +where Action Mailbox will automatically find it: + +```yaml +action_mailbox: + mailgun_api_key: ... +``` + +Alternatively, provide your API key in the `MAILGUN_INGRESS_API_KEY` environment +variable. + +Tell Action Mailbox to accept emails from Mailgun: + +```ruby +# config/environments/production.rb +config.action_mailbox.ingress = :mailgun +``` + +[Configure Mailgun](https://documentation.mailgun.com/en/latest/user_manual.html#receiving-forwarding-and-storing-messages) +to forward inbound emails to `/rails/action_mailbox/mailgun/inbound_emails/mime`. +If your application lived at `https://example.com`, you would specify the +fully-qualified URL `https://example.com/rails/action_mailbox/mailgun/inbound_emails/mime`. + +### Mandrill + +Give Action Mailbox your Mandrill API key so it can authenticate requests to +the Mandrill ingress. + +Use `rails credentials:edit` to add your API key to your application's +encrypted credentials under `action_mailbox.mandrill_api_key`, +where Action Mailbox will automatically find it: + +```yaml +action_mailbox: + mandrill_api_key: ... +``` + +Alternatively, provide your API key in the `MANDRILL_INGRESS_API_KEY` +environment variable. + +Tell Action Mailbox to accept emails from Mandrill: + +```ruby +# config/environments/production.rb +config.action_mailbox.ingress = :mandrill +``` + +[Configure Mandrill](https://mandrill.zendesk.com/hc/en-us/articles/205583197-Inbound-Email-Processing-Overview) +to route inbound emails to `/rails/action_mailbox/mandrill/inbound_emails`. +If your application lived at `https://example.com`, you would specify +the fully-qualified URL `https://example.com/rails/action_mailbox/mandrill/inbound_emails`. + +### Postfix + +Tell Action Mailbox to accept emails from Postfix: + +```ruby +# config/environments/production.rb +config.action_mailbox.ingress = :postfix +``` + +Generate a strong password that Action Mailbox can use to authenticate requests to the Postfix ingress. + +Use `rails credentials:edit` to add the password to your application's encrypted credentials under +`action_mailbox.ingress_password`, where Action Mailbox will automatically find it: + +```yaml +action_mailbox: + ingress_password: ... +``` + +Alternatively, provide the password in the `RAILS_INBOUND_EMAIL_PASSWORD` environment variable. + +[Configure Postfix](https://serverfault.com/questions/258469/how-to-configure-postfix-to-pipe-all-incoming-email-to-a-script) +to pipe inbound emails to `bin/rails action_mailbox:ingress:postfix`, providing +the `URL` of the Postfix ingress and the `INGRESS_PASSWORD` you previously +generated. If your application lived at `https://example.com`, the full command +would look like this: + +```bash +$ URL=https://example.com/rails/action_mailbox/postfix/inbound_emails INGRESS_PASSWORD=... rails action_mailbox:ingress:postfix +``` + +### SendGrid + +Tell Action Mailbox to accept emails from SendGrid: + +```ruby +# config/environments/production.rb +config.action_mailbox.ingress = :sendgrid +``` + +Generate a strong password that Action Mailbox can use to authenticate +requests to the SendGrid ingress. + +Use `rails credentials:edit` to add the password to your application's +encrypted credentials under `action_mailbox.ingress_password`, +where Action Mailbox will automatically find it: + +```yaml +action_mailbox: + ingress_password: ... +``` + +Alternatively, provide the password in the `RAILS_INBOUND_EMAIL_PASSWORD` +environment variable. + +[Configure SendGrid Inbound Parse](https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/) +to forward inbound emails to +`/rails/action_mailbox/sendgrid/inbound_emails` with the username `actionmailbox` +and the password you previously generated. If your application lived at `https://example.com`, +you would configure SendGrid with the following URL: + +``` +https://actionmailbox:PASSWORD@example.com/rails/action_mailbox/sendgrid/inbound_emails +``` + +NOTE: When configuring your SendGrid Inbound Parse webhook, be sure to check the box labeled **“Post the raw, full MIME message.”** Action Mailbox needs the raw MIME message to work. + +## Examples + +Configure basic routing: + +```ruby +# app/mailboxes/application_mailbox.rb +class ApplicationMailbox < ActionMailbox::Base + routing /^save@/i => :forwards + routing /@replies\./i => :replies +end +``` + +Then set up a mailbox: + +```ruby +# Generate new mailbox +$ bin/rails generate mailbox forwards +``` + +```ruby +# app/mailboxes/forwards_mailbox.rb +class ForwardsMailbox < ApplicationMailbox + # Callbacks specify prerequisites to processing + before_processing :require_forward + + def process + if forwarder.buckets.one? + record_forward + else + stage_forward_and_request_more_details + end + end + + private + def require_forward + unless message.forward? + # Use Action Mailers to bounce incoming emails back to sender – this halts processing + bounce_with Forwards::BounceMailer.missing_forward( + inbound_email, forwarder: forwarder + ) + end + end + + def forwarder + @forwarder ||= Person.where(email_address: mail.from) + end + + def record_forward + forwarder.buckets.first.record \ + Forward.new forwarder: forwarder, subject: message.subject, content: mail.content + end + + def stage_forward_and_request_more_details + Forwards::RoutingMailer.choose_project(mail).deliver_now + end +end +``` + +## Incineration of InboundEmails + +By default, an InboundEmail that has been successfully processed will be +incinerated after 30 days. This ensures you're not holding on to people's data +willy-nilly after they may have canceled their accounts or deleted their +content. The intention is that after you've processed an email, you should have +extracted all the data you needed and turned it into domain models and content +on your side of the application. The InboundEmail simply stays in the system +for the extra time to provide debugging and forensics options. + +The actual incineration is done via the `IncinerationJob` that's scheduled +to run after `config.action_mailbox.incinerate_after` time. This value is +by default set to `30.days`, but you can change it in your production.rb +configuration. (Note that this far-future incineration scheduling relies on +your job queue being able to hold jobs for that long.) + +## Working with Action Mailbox in development + +It's helpful to be able to test incoming emails in development without actually +sending and receiving real emails. To accomplish this, there's a conductor +controller mounted at `/rails/conductor/action_mailbox/inbound_emails`, +which gives you an index of all the InboundEmails in the system, their +state of processing, and a form to create a new InboundEmail as well. + +## Testing mailboxes + +Example: + +```ruby +class ForwardsMailboxTest < ActionMailbox::TestCase + test "directly recording a client forward for a forwarder and forwardee corresponding to one project" do + assert_difference -> { people(:david).buckets.first.recordings.count } do + receive_inbound_email_from_mail \ + to: 'save@example.com', + from: people(:david).email_address, + subject: "Fwd: Status update?", + body: <<~BODY + --- Begin forwarded message --- + From: Frank Holland <frank@microsoft.com> + + What's the status? + BODY + end + + recording = people(:david).buckets.first.recordings.last + assert_equal people(:david), recording.creator + assert_equal "Status update?", recording.forward.subject + assert_match "What's the status?", recording.forward.content.to_s + end +end +``` diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md index 1acb993cad..16db433bd4 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -3,13 +3,13 @@ Action Mailer Basics ==================== -This guide provides you with all you need to get started in sending and -receiving emails from and to your application, and many internals of Action +This guide provides you with all you need to get started in sending +emails from and to your application, and many internals of Action Mailer. It also covers how to test your mailers. After reading this guide, you will know: -* How to send and receive email within a Rails application. +* How to send email within a Rails application. * How to generate and edit an Action Mailer class and mailer view. * How to configure Action Mailer for your environment. * How to test your Action Mailer classes. @@ -427,7 +427,7 @@ If you would like to render a template located outside of the default `app/views ```ruby class UserMailer < ApplicationMailer prepend_view_path "custom/path/to/mailer/view" - + # This will try to load "custom/path/to/mailer/view/welcome_email" template def welcome_email # ... @@ -651,48 +651,8 @@ class UserMailer < ApplicationMailer end ``` -Receiving Emails ----------------- - -Receiving and parsing emails with Action Mailer can be a rather complex -endeavor. Before your email reaches your Rails app, you would have had to -configure your system to somehow forward emails to your app, which needs to be -listening for that. So, to receive emails in your Rails app you'll need to: - -* Implement a `receive` method in your mailer. - -* Configure your email server to forward emails from the address(es) you would - like your app to receive to `/path/to/app/bin/rails runner - 'UserMailer.receive(STDIN.read)'`. - -Once a method called `receive` is defined in any mailer, Action Mailer will -parse the raw incoming email into an email object, decode it, instantiate a new -mailer, and pass the email object to the mailer `receive` instance -method. Here's an example: - -```ruby -class UserMailer < ApplicationMailer - def receive(email) - page = Page.find_by(address: email.to.first) - page.emails.create( - subject: email.subject, - body: email.body - ) - - if email.has_attachments? - email.attachments.each do |attachment| - page.attachments.create({ - file: attachment, - description: email.subject - }) - end - end - end -end -``` - Action Mailer Callbacks ---------------------------- +----------------------- Action Mailer allows for you to specify a `before_action`, `after_action` and `around_action`. @@ -882,7 +842,7 @@ class EmailDeliveryObserver end end ``` -Like interceptors, you need to register observers with the Action Mailer framework. You can do this in an initializer file +Like interceptors, you need to register observers with the Action Mailer framework. You can do this in an initializer file `config/initializers/email_delivery_observer.rb` ```ruby diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md index 4d195988f8..905c76e5c1 100644 --- a/guides/source/active_record_migrations.md +++ b/guides/source/active_record_migrations.md @@ -126,7 +126,7 @@ generator to handle making it for you: $ rails generate migration AddPartNumberToProducts ``` -This will create an empty but appropriately named migration: +This will create an appropriately named empty migration: ```ruby class AddPartNumberToProducts < ActiveRecord::Migration[5.0] @@ -135,9 +135,14 @@ class AddPartNumberToProducts < ActiveRecord::Migration[5.0] end ``` -If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is -followed by a list of column names and types then a migration containing the -appropriate `add_column` and `remove_column` statements will be created. +This generator can do much more than append a timestamp to the file name. +Based on naming conventions and additional (optional) arguments it can +also start fleshing out the migration. + +If the migration name is of the form "AddColumnToTable" or +"RemoveColumnFromTable" and is followed by a list of column names and +types then a migration containing the appropriate `add_column` and +`remove_column` statements will be created. ```bash $ rails generate migration AddPartNumberToProducts part_number:string diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 6b0554bb5f..3db46bc42e 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -2132,30 +2132,6 @@ The methods `second`, `third`, `fourth`, and `fifth` return the corresponding el NOTE: Defined in `active_support/core_ext/array/access.rb`. -### Adding Elements - -#### `prepend` - -This method is an alias of `Array#unshift`. - -```ruby -%w(a b c d).prepend('e') # => ["e", "a", "b", "c", "d"] -[].prepend(10) # => [10] -``` - -NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`. - -#### `append` - -This method is an alias of `Array#<<`. - -```ruby -%w(a b c d).append('e') # => ["a", "b", "c", "d", "e"] -[].append([1,2]) # => [[1, 2]] -``` - -NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`. - ### Extracting The method `extract!` removes and returns the elements for which the block returns a true value. @@ -2646,48 +2622,6 @@ There's also the bang variant `except!` that removes keys in the very receiver. NOTE: Defined in `active_support/core_ext/hash/except.rb`. -#### `transform_keys` and `transform_keys!` - -The method `transform_keys` accepts a block and returns a hash that has applied the block operations to each of the keys in the receiver: - -```ruby -{nil => nil, 1 => 1, a: :a}.transform_keys { |key| key.to_s.upcase } -# => {"" => nil, "1" => 1, "A" => :a} -``` - -In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash: - -```ruby -{"a" => 1, a: 2}.transform_keys { |key| key.to_s.upcase } -# The result could either be -# => {"A"=>2} -# or -# => {"A"=>1} -``` - -This method may be useful for example to build specialized conversions. For instance `stringify_keys` and `symbolize_keys` use `transform_keys` to perform their key conversions: - -```ruby -def stringify_keys - transform_keys { |key| key.to_s } -end -... -def symbolize_keys - transform_keys { |key| key.to_sym rescue key } -end -``` - -There's also the bang variant `transform_keys!` that applies the block operations to keys in the very receiver. - -Besides that, one can use `deep_transform_keys` and `deep_transform_keys!` to perform the block operation on all the keys in the given hash and all the hashes nested into it. An example of the result is: - -```ruby -{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys { |key| key.to_s.upcase } -# => {""=>nil, "1"=>1, "NESTED"=>{"A"=>3, "5"=>5}} -``` - -NOTE: Defined in `active_support/core_ext/hash/keys.rb`. - #### `stringify_keys` and `stringify_keys!` The method `stringify_keys` returns a hash that has a stringified version of the keys in the receiver. It does so by sending `to_s` to them: @@ -2795,26 +2729,7 @@ NOTE: Defined in `active_support/core_ext/hash/keys.rb`. ### Slicing -Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes: - -```ruby -{a: 1, b: 2, c: 3}.slice(:a, :c) -# => {:a=>1, :c=>3} - -{a: 1, b: 2, c: 3}.slice(:b, :X) -# => {:b=>2} # non-existing keys are ignored -``` - -If the receiver responds to `convert_key` keys are normalized: - -```ruby -{a: 1, b: 2}.with_indifferent_access.slice("a") -# => {:a=>1} -``` - -NOTE. Slicing may come in handy for sanitizing option hashes with a white list of keys. - -There's also `slice!` which in addition to perform a slice in place returns what's removed: +The method `slice!` replaces the hash with only the given keys and returns a hash containing the removed key/value pairs. ```ruby hash = {a: 1, b: 2} diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md index 64db141381..f9b8f3208d 100644 --- a/guides/source/active_support_instrumentation.md +++ b/guides/source/active_support_instrumentation.md @@ -291,32 +291,6 @@ INFO. The adapters will add their own data as well. Action Mailer ------------- -### receive.action_mailer - -| Key | Value | -| ------------- | -------------------------------------------- | -| `:mailer` | Name of the mailer class | -| `:message_id` | ID of the message, generated by the Mail gem | -| `:subject` | Subject of the mail | -| `:to` | To address(es) of the mail | -| `:from` | From address of the mail | -| `:bcc` | BCC addresses of the mail | -| `:cc` | CC addresses of the mail | -| `:date` | Date of the mail | -| `:mail` | The encoded form of the mail | - -```ruby -{ - mailer: "Notification", - message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail", - subject: "Rails Guides", - to: ["users@rails.com", "dhh@rails.com"], - from: ["me@rails.com"], - date: Sat, 10 Mar 2012 14:18:09 +0100, - mail: "..." # omitted for brevity -} -``` - ### deliver.action_mailer | Key | Value | @@ -648,6 +622,18 @@ ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*a end ``` +You may also pass block with only one argument, it will yield an event object to the block: + +```ruby +ActiveSupport::Notifications.subscribe "process_action.action_controller" do |event| + event.name # => "process_action.action_controller" + event.duration # => 10 (in milliseconds) + event.payload # => {:extra=>information} + + Rails.logger.info "#{event} Received!" +end +``` + Most times you only care about the data itself. Here is a shortcut to just get the data. ```ruby @@ -672,7 +658,7 @@ Creating custom events Adding your own events is easy as well. `ActiveSupport::Notifications` will take care of all the heavy lifting for you. Simply call `instrument` with a `name`, `payload` and a block. The notification will be sent after the block returns. `ActiveSupport` will generate the start and end times -and add the instrumenter's unique ID. All data passed into the `instrument` call will make +and add the instrumenter's unique ID. All data passed into the `instrument` call will make it into the payload. Here's an example: diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md index 500e230ff9..e7faa5c330 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -1101,7 +1101,7 @@ Windows you have a JavaScript runtime installed in your operating system. -### Serving GZipped version of assets +### GZipping your assets By default, gzipped version of compiled assets will be generated, along with the non-gzipped version of assets. Gzipped assets help reduce the transmission @@ -1111,6 +1111,8 @@ of data over the wire. You can configure this by setting the `gzip` flag. config.assets.gzip = false # disable gzipped assets generation ``` +Refer to your web server's documentation for instructions on how to serve gzipped assets. + ### Using Your Own Compressor The compressor config settings for CSS and JavaScript also take any object. diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 029ae1a5ff..7193278581 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -815,7 +815,7 @@ normal Rails server. config.active_storage.paths[:ffprobe] = '/usr/local/bin/ffprobe' ``` -* `config.active_storage.variable_content_types` accepts an array of strings indicating the content types that Active Storage can transform through ImageMagick. The default is `%w(image/png image/gif image/jpg image/jpeg image/pjpeg image/vnd.adobe.photoshop image/vnd.microsoft.icon)`. +* `config.active_storage.variable_content_types` accepts an array of strings indicating the content types that Active Storage can transform through ImageMagick. The default is `%w(image/png image/gif image/jpg image/jpeg image/pjpeg image/tiff image/vnd.adobe.photoshop image/vnd.microsoft.icon)`. * `config.active_storage.content_types_to_serve_as_binary` accepts an array of strings indicating the content types that Active Storage will always serve as an attachment, rather than inline. The default is `%w(text/html text/javascript image/svg+xml application/postscript application/x-shockwave-flash text/xml application/xml application/xhtml+xml)`. @@ -1404,7 +1404,7 @@ Custom configuration You can configure your own code through the Rails configuration object with custom configuration under either the `config.x` namespace, or `config` directly. The key difference between these two is that you should be using `config.x` if you -are defining _nested_ configuration (ex: `config.x.nested.nested.hi`), and just +are defining _nested_ configuration (ex: `config.x.nested.hi`), and just `config` for _single level_ configuration (ex: `config.hello`). ```ruby diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml index 25c159d471..0f836bdf48 100644 --- a/guides/source/documents.yaml +++ b/guides/source/documents.yaml @@ -74,7 +74,12 @@ - name: Action Mailer Basics url: action_mailer_basics.html - description: This guide describes how to use Action Mailer to send and receive emails. + description: This guide describes how to use Action Mailer to send emails. + - + name: Action Mailbox Basics + work_in_progress: true + url: action_mailbox_basics.html + description: This guide describes how to use Action Mailbox to receive emails. - name: Active Job Basics url: active_job_basics.html diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index e2f558d74c..264c94326e 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -90,7 +90,7 @@ $ ruby -v ruby 2.5.0 ``` -Rails requires Ruby version 2.4.1 or later. If the version number returned is +Rails requires Ruby version 2.5.0 or later. If the version number returned is less than that number, you'll need to install a fresh copy of Ruby. TIP: To quickly install Ruby and Ruby on Rails on your system in Windows, you can use diff --git a/guides/source/testing.md b/guides/source/testing.md index 9541598b26..f34f9d95f4 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -473,8 +473,8 @@ takes your entire test suite to run. ### Parallel testing with processes The default parallelization method is to fork processes using Ruby's DRb system. The processes -are forked based on the number of workers provided. The default is 2, but can be changed by the -number passed to the parallelize method. +are forked based on the number of workers provided. The default number is the actual core count +on the machine you are on, but can be changed by the number passed to the parallelize method. To enable parallelization add the following to your `test_helper.rb`: @@ -516,7 +516,7 @@ class ActiveSupport::TestCase # cleanup databases end - parallelize(workers: 2) + parallelize(workers: :number_of_processors) end ``` @@ -531,7 +531,7 @@ To change the parallelization method to use threads over forks put the following ```ruby class ActiveSupport::TestCase - parallelize(workers: 2, with: :threads) + parallelize(workers: :number_of_processors, with: :threads) end ``` diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index e74985c5b0..2682c6ffd7 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -35,7 +35,7 @@ You can find a list of all released Rails versions [here](https://rubygems.org/g Rails generally stays close to the latest released Ruby version when it's released: -* Rails 6 requires Ruby 2.4.1 or newer. +* Rails 6 requires Ruby 2.5.0 or newer. * Rails 5 requires Ruby 2.2.2 or newer. * Rails 4 prefers Ruby 2.0 and requires 1.9.3 or newer. * Rails 3.2.x is the last branch to support Ruby 1.8.7. |