mirror of https://github.com/rails/rails
Merge pull request #46250 from missy-davies/md/capitalize-heading
Capitalize heading to match style guidelines [ci-skip]
This commit is contained in:
commit
d322d9b448
|
@ -792,7 +792,7 @@ connections as you have workers. The default worker pool size is set to 4, so
|
||||||
that means you have to make at least 4 database connections available.
|
that means you have to make at least 4 database connections available.
|
||||||
You can change that in `config/database.yml` through the `pool` attribute.
|
You can change that in `config/database.yml` through the `pool` attribute.
|
||||||
|
|
||||||
### Client-side logging
|
### Client-side Logging
|
||||||
|
|
||||||
Client-side logging is disabled by default. You can enable this by setting the `ActionCable.logger.enabled` to true.
|
Client-side logging is disabled by default. You can enable this by setting the `ActionCable.logger.enabled` to true.
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ When this form is submitted, the value of `params[:client]` will be `{ "name" =>
|
||||||
|
|
||||||
The `params` object acts like a Hash, but lets you use symbols and strings interchangeably as keys.
|
The `params` object acts like a Hash, but lets you use symbols and strings interchangeably as keys.
|
||||||
|
|
||||||
### JSON parameters
|
### JSON Parameters
|
||||||
|
|
||||||
If you're writing a web service application, you might find yourself more comfortable accepting parameters in JSON format. If the "Content-Type" header of your request is set to "application/json", Rails will automatically load your parameters into the `params` hash, which you can access as you would normally.
|
If you're writing a web service application, you might find yourself more comfortable accepting parameters in JSON format. If the "Content-Type" header of your request is set to "application/json", Rails will automatically load your parameters into the `params` hash, which you can access as you would normally.
|
||||||
|
|
||||||
|
@ -680,7 +680,7 @@ If you use the cookie session store, this would apply to the `session` and
|
||||||
|
|
||||||
[`cookies`]: https://api.rubyonrails.org/classes/ActionController/Cookies.html#method-i-cookies
|
[`cookies`]: https://api.rubyonrails.org/classes/ActionController/Cookies.html#method-i-cookies
|
||||||
|
|
||||||
Rendering XML and JSON data
|
Rendering XML and JSON Data
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
ActionController makes it extremely easy to render `XML` or `JSON` data. If you've generated a controller using scaffolding, it would look something like this:
|
ActionController makes it extremely easy to render `XML` or `JSON` data. If you've generated a controller using scaffolding, it would look something like this:
|
||||||
|
@ -1274,7 +1274,7 @@ NOTE: Certain exceptions are only rescuable from the `ApplicationController` cla
|
||||||
|
|
||||||
[`rescue_from`]: https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html#method-i-rescue_from
|
[`rescue_from`]: https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html#method-i-rescue_from
|
||||||
|
|
||||||
Force HTTPS protocol
|
Force HTTPS Protocol
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
If you'd like to ensure that communication to your controller is only possible
|
If you'd like to ensure that communication to your controller is only possible
|
||||||
|
|
|
@ -340,7 +340,7 @@ your job queue being able to hold jobs for that long.)
|
||||||
|
|
||||||
[`config.action_mailbox.incinerate_after`]: configuring.html#config-action-mailbox-incinerate-after
|
[`config.action_mailbox.incinerate_after`]: configuring.html#config-action-mailbox-incinerate-after
|
||||||
|
|
||||||
## Working with Action Mailbox in development
|
## Working with Action Mailbox in Development
|
||||||
|
|
||||||
It's helpful to be able to test incoming emails in development without actually
|
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
|
sending and receiving real emails. To accomplish this, there's a conductor
|
||||||
|
@ -348,7 +348,7 @@ controller mounted at `/rails/conductor/action_mailbox/inbound_emails`,
|
||||||
which gives you an index of all the InboundEmails in the system, their
|
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.
|
state of processing, and a form to create a new InboundEmail as well.
|
||||||
|
|
||||||
## Testing mailboxes
|
## Testing Mailboxes
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ What is Action Mailer?
|
||||||
Action Mailer allows you to send emails from your application using mailer classes
|
Action Mailer allows you to send emails from your application using mailer classes
|
||||||
and views.
|
and views.
|
||||||
|
|
||||||
### Mailers are similar to controllers
|
### Mailers are Similar to Controllers
|
||||||
|
|
||||||
They inherit from [`ActionMailer::Base`][] and live in `app/mailers`. Mailers also work
|
They inherit from [`ActionMailer::Base`][] and live in `app/mailers`. Mailers also work
|
||||||
very similarly to controllers. Some examples of similarities are enumerated below.
|
very similarly to controllers. Some examples of similarities are enumerated below.
|
||||||
|
@ -259,7 +259,7 @@ access it with the [`message`][] method on the `ActionMailer::MessageDelivery` o
|
||||||
[`message`]: https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-message
|
[`message`]: https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-message
|
||||||
[`with`]: https://api.rubyonrails.org/classes/ActionMailer/Parameterized/ClassMethods.html#method-i-with
|
[`with`]: https://api.rubyonrails.org/classes/ActionMailer/Parameterized/ClassMethods.html#method-i-with
|
||||||
|
|
||||||
### Auto encoding header values
|
### Auto Encoding Header Values
|
||||||
|
|
||||||
Action Mailer handles the auto encoding of multibyte characters inside of
|
Action Mailer handles the auto encoding of multibyte characters inside of
|
||||||
headers and bodies.
|
headers and bodies.
|
||||||
|
@ -352,7 +352,7 @@ Action Mailer 3.0 makes inline attachments, which involved a lot of hacking in p
|
||||||
<%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
|
<%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Sending Email To Multiple Recipients
|
#### Sending Email to Multiple Recipients
|
||||||
|
|
||||||
It is possible to send email to one or more recipients in one email (e.g.,
|
It is possible to send email to one or more recipients in one email (e.g.,
|
||||||
informing all admins of a new signup) by setting the list of emails to the `:to`
|
informing all admins of a new signup) by setting the list of emails to the `:to`
|
||||||
|
@ -374,7 +374,7 @@ end
|
||||||
The same format can be used to set carbon copy (Cc:) and blind carbon copy
|
The same format can be used to set carbon copy (Cc:) and blind carbon copy
|
||||||
(Bcc:) recipients, by using the `:cc` and `:bcc` keys respectively.
|
(Bcc:) recipients, by using the `:cc` and `:bcc` keys respectively.
|
||||||
|
|
||||||
#### Sending Email With Name
|
#### Sending Email with Name
|
||||||
|
|
||||||
Sometimes you wish to show the name of the person instead of just their email
|
Sometimes you wish to show the name of the person instead of just their email
|
||||||
address when they receive the email. You can use [`email_address_with_name`][] for
|
address when they receive the email. You can use [`email_address_with_name`][] for
|
||||||
|
@ -473,7 +473,7 @@ You can also consider using the [`append_view_path`][] method.
|
||||||
[`append_view_path`]: https://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-append_view_path
|
[`append_view_path`]: https://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-append_view_path
|
||||||
[`prepend_view_path`]: https://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-prepend_view_path
|
[`prepend_view_path`]: https://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-prepend_view_path
|
||||||
|
|
||||||
#### Caching mailer view
|
#### Caching Mailer View
|
||||||
|
|
||||||
You can perform fragment caching in mailer views like in application views using the [`cache`][] method.
|
You can perform fragment caching in mailer views like in application views using the [`cache`][] method.
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ NOTE: non-`GET` links require [rails-ujs](https://github.com/rails/rails/blob/ma
|
||||||
[jQuery UJS](https://github.com/rails/jquery-ujs), and won't work in mailer templates.
|
[jQuery UJS](https://github.com/rails/jquery-ujs), and won't work in mailer templates.
|
||||||
They will result in normal `GET` requests.
|
They will result in normal `GET` requests.
|
||||||
|
|
||||||
### Adding images in Action Mailer Views
|
### Adding Images in Action Mailer Views
|
||||||
|
|
||||||
Unlike controllers, the mailer instance doesn't have any context about the
|
Unlike controllers, the mailer instance doesn't have any context about the
|
||||||
incoming request so you'll need to provide the `:asset_host` parameter yourself.
|
incoming request so you'll need to provide the `:asset_host` parameter yourself.
|
||||||
|
|
|
@ -25,7 +25,7 @@ RichText model that's associated with any existing Active Record model in the ap
|
||||||
Any embedded images (or other attachments) are automatically stored using
|
Any embedded images (or other attachments) are automatically stored using
|
||||||
Active Storage and associated with the included RichText model.
|
Active Storage and associated with the included RichText model.
|
||||||
|
|
||||||
## Trix compared to other rich text editors
|
## Trix Compared to Other Rich Text Editors
|
||||||
|
|
||||||
Most WYSIWYG editors are wrappers around HTML’s `contenteditable` and `execCommand` APIs,
|
Most WYSIWYG editors are wrappers around HTML’s `contenteditable` and `execCommand` APIs,
|
||||||
designed by Microsoft to support live editing of web pages in Internet Explorer 5.5,
|
designed by Microsoft to support live editing of web pages in Internet Explorer 5.5,
|
||||||
|
@ -61,7 +61,7 @@ After the installation is complete, a Rails app should have the following change
|
||||||
|
|
||||||
2. The `trix` stylesheet will be included together with Action Text styles in your `application.css` file.
|
2. The `trix` stylesheet will be included together with Action Text styles in your `application.css` file.
|
||||||
|
|
||||||
## Creating Rich Text content
|
## Creating Rich Text Content
|
||||||
|
|
||||||
Add a rich text field to an existing model:
|
Add a rich text field to an existing model:
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ end
|
||||||
|
|
||||||
[`rich_text_area`]: https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-rich_text_area
|
[`rich_text_area`]: https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-rich_text_area
|
||||||
|
|
||||||
## Rendering Rich Text content
|
## Rendering Rich Text Content
|
||||||
|
|
||||||
By default, Action Text will render rich text content inside an element with the
|
By default, Action Text will render rich text content inside an element with the
|
||||||
`.trix-content` class:
|
`.trix-content` class:
|
||||||
|
@ -214,7 +214,7 @@ By default, all `ActiveRecord::Base` descendants mix-in
|
||||||
|
|
||||||
[global-id]: https://github.com/rails/globalid#usage
|
[global-id]: https://github.com/rails/globalid#usage
|
||||||
|
|
||||||
## Avoid N+1 queries
|
## Avoid N+1 Queries
|
||||||
|
|
||||||
If you wish to preload the dependent `ActionText::RichText` model, assuming your rich text field is named `content`, you can use the named scope:
|
If you wish to preload the dependent `ActionText::RichText` model, assuming your rich text field is named `content`, you can use the named scope:
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ Message.all.with_rich_text_content # Preload the body without attachments.
|
||||||
Message.all.with_rich_text_content_and_embeds # Preload both body and attachments.
|
Message.all.with_rich_text_content_and_embeds # Preload both body and attachments.
|
||||||
```
|
```
|
||||||
|
|
||||||
## API / Backend development
|
## API / Backend Development
|
||||||
|
|
||||||
1. A backend API (for example, using JSON) needs a separate endpoint for uploading files that creates an `ActiveStorage::Blob` and returns its `attachable_sgid`:
|
1. A backend API (for example, using JSON) needs a separate endpoint for uploading files that creates an `ActiveStorage::Blob` and returns its `attachable_sgid`:
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ After reading this guide, you will know:
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Overview of helpers provided by Action View
|
Overview of Helpers Provided by Action View
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
WIP: Not all the helpers are listed here. For a full list see the [API documentation](https://api.rubyonrails.org/classes/ActionView/Helpers.html)
|
WIP: Not all the helpers are listed here. For a full list see the [API documentation](https://api.rubyonrails.org/classes/ActionView/Helpers.html)
|
||||||
|
|
|
@ -204,7 +204,7 @@ This will render a file named `_menu.html.erb` at that point within the view tha
|
||||||
|
|
||||||
That code will pull in the partial from `app/views/shared/_menu.html.erb`.
|
That code will pull in the partial from `app/views/shared/_menu.html.erb`.
|
||||||
|
|
||||||
#### Using Partials to simplify Views
|
#### Using Partials to Simplify Views
|
||||||
|
|
||||||
One way to use partials is to treat them as the equivalent of subroutines; a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looks like this:
|
One way to use partials is to treat them as the equivalent of subroutines; a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looks like this:
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ One way to use partials is to treat them as the equivalent of subroutines; a way
|
||||||
|
|
||||||
Here, the `_ad_banner.html.erb` and `_footer.html.erb` partials could contain content that is shared among many pages in your application. You don't need to see the details of these sections when you're concentrating on a particular page.
|
Here, the `_ad_banner.html.erb` and `_footer.html.erb` partials could contain content that is shared among many pages in your application. You don't need to see the details of these sections when you're concentrating on a particular page.
|
||||||
|
|
||||||
#### `render` without `partial` and `locals` options
|
#### `render` without `partial` and `locals` Options
|
||||||
|
|
||||||
In the above example, `render` takes 2 options: `partial` and `locals`. But if
|
In the above example, `render` takes 2 options: `partial` and `locals`. But if
|
||||||
these are the only options you want to pass, you can skip using these options.
|
these are the only options you want to pass, you can skip using these options.
|
||||||
|
@ -239,7 +239,7 @@ You can also do:
|
||||||
<%= render "product", product: @product %>
|
<%= render "product", product: @product %>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### The `as` and `object` options
|
#### The `as` and `object` Options
|
||||||
|
|
||||||
By default `ActionView::Partials::PartialRenderer` has its object in a local variable with the same name as the template. So, given:
|
By default `ActionView::Partials::PartialRenderer` has its object in a local variable with the same name as the template. So, given:
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ views are located. By default, it only looks inside the `app/views` directory.
|
||||||
We can add other locations and give them certain precedence when resolving
|
We can add other locations and give them certain precedence when resolving
|
||||||
paths using the `prepend_view_path` and `append_view_path` methods.
|
paths using the `prepend_view_path` and `append_view_path` methods.
|
||||||
|
|
||||||
### Prepend view path
|
### Prepend View Path
|
||||||
|
|
||||||
This can be helpful for example when we want to put views inside a different
|
This can be helpful for example when we want to put views inside a different
|
||||||
directory for subdomains.
|
directory for subdomains.
|
||||||
|
@ -411,7 +411,7 @@ prepend_view_path "app/views/#{request.subdomain}"
|
||||||
|
|
||||||
Then Action View will look first in this directory when resolving views.
|
Then Action View will look first in this directory when resolving views.
|
||||||
|
|
||||||
### Append view path
|
### Append View Path
|
||||||
|
|
||||||
Similarly, we can append paths:
|
Similarly, we can append paths:
|
||||||
|
|
||||||
|
|
|
@ -343,7 +343,7 @@ class ApplicationJob < ActiveJob::Base
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
### Available callbacks
|
### Available Callbacks
|
||||||
|
|
||||||
* [`before_enqueue`][]
|
* [`before_enqueue`][]
|
||||||
* [`around_enqueue`][]
|
* [`around_enqueue`][]
|
||||||
|
@ -394,7 +394,7 @@ UserMailer.welcome(@user).deliver_later # Email will be localized to Esperanto.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Supported types for arguments
|
Supported Types for Arguments
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
ActiveJob supports the following types of arguments by default:
|
ActiveJob supports the following types of arguments by default:
|
||||||
|
@ -513,7 +513,7 @@ If an exception from a job is not rescued, then the job is referred to as "faile
|
||||||
|
|
||||||
[`rescue_from`]: https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html#method-i-rescue_from
|
[`rescue_from`]: https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html#method-i-rescue_from
|
||||||
|
|
||||||
### Retrying or Discarding failed jobs
|
### Retrying or Discarding Failed Jobs
|
||||||
|
|
||||||
A failed job will not be retried, unless configured otherwise.
|
A failed job will not be retried, unless configured otherwise.
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ class Person
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Querying object directly for its list of all changed attributes.
|
#### Querying an Object Directly for its List of All Changed Attributes
|
||||||
|
|
||||||
```irb
|
```irb
|
||||||
irb> person = Person.new
|
irb> person = Person.new
|
||||||
|
@ -231,7 +231,7 @@ irb> person.changes
|
||||||
=> {"first_name"=>[nil, "First Name"]}
|
=> {"first_name"=>[nil, "First Name"]}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Attribute-based accessor methods
|
#### Attribute-based Accessor Methods
|
||||||
|
|
||||||
Track whether the particular attribute has been changed or not.
|
Track whether the particular attribute has been changed or not.
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ But, under the hood, the executed SQL looks like this:
|
||||||
INSERT INTO `articles` (`title`) VALUES ('{\"p\":\"n7J0/ol+a7DRMeaE\",\"h\":{\"iv\":\"DXZMDWUKfp3bg/Yu\",\"at\":\"X1/YjMHbHD4talgF9dt61A==\"}}')
|
INSERT INTO `articles` (`title`) VALUES ('{\"p\":\"n7J0/ol+a7DRMeaE\",\"h\":{\"iv\":\"DXZMDWUKfp3bg/Yu\",\"at\":\"X1/YjMHbHD4talgF9dt61A==\"}}')
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Important: About storage and column size
|
#### Important: About Storage and Column Size
|
||||||
|
|
||||||
Encryption requires extra space because of Base64 encoding and the metadata stored along with the encrypted payloads. When using the built-in envelope encryption key provider, you can estimate the worst-case overhead at around 255 bytes. This overhead is negligible at larger sizes. Not only because it gets diluted but because the library uses compression by default, which can offer up to 30% storage savings over the unencrypted version for larger payloads.
|
Encryption requires extra space because of Base64 encoding and the metadata stored along with the encrypted payloads. When using the built-in envelope encryption key provider, you can estimate the worst-case overhead at around 255 bytes. This overhead is negligible at larger sizes. Not only because it gets diluted but because the library uses compression by default, which can offer up to 30% storage savings over the unencrypted version for larger payloads.
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ The following features are not (yet) supported:
|
||||||
|
|
||||||
* Load balancing replicas
|
* Load balancing replicas
|
||||||
|
|
||||||
## Setting up your application
|
## Setting up Your Application
|
||||||
|
|
||||||
While Rails tries to do most of the work for you there are still some steps you'll
|
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.
|
need to do to get your application ready for multiple databases.
|
||||||
|
@ -274,7 +274,7 @@ $ bin/rails generate scaffold Dog name:string --database animals --parent Animal
|
||||||
This will skip generating `AnimalsRecord` since you've indicated to Rails that you want to
|
This will skip generating `AnimalsRecord` since you've indicated to Rails that you want to
|
||||||
use a different parent class.
|
use a different parent class.
|
||||||
|
|
||||||
## Activating automatic role switching
|
## Activating Automatic Role Switching
|
||||||
|
|
||||||
Finally, in order to use the read-only replica in your application, you'll need to activate
|
Finally, in order to use the read-only replica in your application, you'll need to activate
|
||||||
the middleware for automatic switching.
|
the middleware for automatic switching.
|
||||||
|
@ -332,7 +332,7 @@ config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelec
|
||||||
config.active_record.database_resolver_context = MyCookieResolver
|
config.active_record.database_resolver_context = MyCookieResolver
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using manual connection switching
|
## Using Manual Connection Switching
|
||||||
|
|
||||||
There are some cases where you may want your application to connect to a writer or a replica
|
There are some cases where you may want your application to connect to a writer or a replica
|
||||||
and the automatic connection switching isn't adequate. For example, you may know that for a
|
and the automatic connection switching isn't adequate. For example, you may know that for a
|
||||||
|
@ -367,7 +367,7 @@ ActiveRecord::Base.connected_to(role: :reading, prevent_writes: true) do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
## Horizontal sharding
|
## Horizontal Sharding
|
||||||
|
|
||||||
Horizontal sharding is when you split up your database to reduce the number of rows on each
|
Horizontal sharding is when you split up your database to reduce the number of rows on each
|
||||||
database server, but maintain the same schema across "shards". This is commonly called "multi-tenant"
|
database server, but maintain the same schema across "shards". This is commonly called "multi-tenant"
|
||||||
|
@ -432,7 +432,7 @@ ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one) do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
## Activating automatic shard switching
|
## Activating Automatic Shard Switching
|
||||||
|
|
||||||
Applications are able to automatically switch shards per request using the provided
|
Applications are able to automatically switch shards per request using the provided
|
||||||
middleware.
|
middleware.
|
||||||
|
@ -515,7 +515,7 @@ end
|
||||||
`ActiveRecord::Base.connected_to` maintains the ability to switch
|
`ActiveRecord::Base.connected_to` maintains the ability to switch
|
||||||
connections globally.
|
connections globally.
|
||||||
|
|
||||||
### Handling associations with joins across databases
|
### Handling Associations with Joins across Databases
|
||||||
|
|
||||||
As of Rails 7.0+, Active Record has an option for handling associations that would perform
|
As of Rails 7.0+, Active Record has an option for handling associations that would perform
|
||||||
a join across multiple databases. If you have a has many through or a has one through association
|
a join across multiple databases. If you have a has many through or a has one through association
|
||||||
|
|
|
@ -689,7 +689,7 @@ irb> Article.count
|
||||||
NOTE: This application only cares about non-archived `Articles`. A view also
|
NOTE: This application only cares about non-archived `Articles`. A view also
|
||||||
allows for conditions so we can exclude the archived `Articles` directly.
|
allows for conditions so we can exclude the archived `Articles` directly.
|
||||||
|
|
||||||
Structure dumps
|
Structure Dumps
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
If your `config.active_record.schema_format` is `:sql`, Rails will call `pg_dump` to generate a
|
If your `config.active_record.schema_format` is `:sql`, Rails will call `pg_dump` to generate a
|
||||||
|
|
|
@ -899,7 +899,7 @@ FROM orders
|
||||||
GROUP BY created_at
|
GROUP BY created_at
|
||||||
```
|
```
|
||||||
|
|
||||||
### Total of grouped items
|
### Total of Grouped Items
|
||||||
|
|
||||||
To get the total of grouped items on a single query, call [`count`][] after the `group`.
|
To get the total of grouped items on a single query, call [`count`][] after the `group`.
|
||||||
|
|
||||||
|
@ -1604,7 +1604,7 @@ end
|
||||||
|
|
||||||
[`scope`]: https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope
|
[`scope`]: https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope
|
||||||
|
|
||||||
### Passing in arguments
|
### Passing in Arguments
|
||||||
|
|
||||||
Your scope can take arguments:
|
Your scope can take arguments:
|
||||||
|
|
||||||
|
@ -1636,7 +1636,7 @@ These methods will still be accessible on the association objects:
|
||||||
irb> author.books.costs_more_than(100.10)
|
irb> author.books.costs_more_than(100.10)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using conditionals
|
### Using Conditionals
|
||||||
|
|
||||||
Your scope can utilize conditionals:
|
Your scope can utilize conditionals:
|
||||||
|
|
||||||
|
@ -1658,7 +1658,7 @@ end
|
||||||
|
|
||||||
However, there is one important caveat: A scope will always return an `ActiveRecord::Relation` object, even if the conditional evaluates to `false`, whereas a class method, will return `nil`. This can cause `NoMethodError` when chaining class methods with conditionals, if any of the conditionals return `false`.
|
However, there is one important caveat: A scope will always return an `ActiveRecord::Relation` object, even if the conditional evaluates to `false`, whereas a class method, will return `nil`. This can cause `NoMethodError` when chaining class methods with conditionals, if any of the conditionals return `false`.
|
||||||
|
|
||||||
### Applying a default scope
|
### Applying a Default Scope
|
||||||
|
|
||||||
If we wish for a scope to be applied across all queries to the model we can use the
|
If we wish for a scope to be applied across all queries to the model we can use the
|
||||||
[`default_scope`][] method within the model itself.
|
[`default_scope`][] method within the model itself.
|
||||||
|
@ -1720,7 +1720,7 @@ irb> Book.new
|
||||||
|
|
||||||
[`default_scope`]: https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html#method-i-default_scope
|
[`default_scope`]: https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html#method-i-default_scope
|
||||||
|
|
||||||
### Merging of scopes
|
### Merging of Scopes
|
||||||
|
|
||||||
Just like `where` clauses, scopes are merged using `AND` conditions.
|
Just like `where` clauses, scopes are merged using `AND` conditions.
|
||||||
|
|
||||||
|
@ -1895,7 +1895,7 @@ There are some examples below. This guide won't cover all the possibilities, jus
|
||||||
When an Active Record method is called, the query is not immediately generated and sent to the database.
|
When an Active Record method is called, the query is not immediately generated and sent to the database.
|
||||||
The query is sent only when the data is actually needed. So each example below generates a single query.
|
The query is sent only when the data is actually needed. So each example below generates a single query.
|
||||||
|
|
||||||
### Retrieving filtered data from multiple tables
|
### Retrieving Filtered Data from Multiple Tables
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
Customer
|
Customer
|
||||||
|
@ -1914,7 +1914,7 @@ INNER JOIN reviews
|
||||||
WHERE (reviews.created_at > '2019-01-08')
|
WHERE (reviews.created_at > '2019-01-08')
|
||||||
```
|
```
|
||||||
|
|
||||||
### Retrieving specific data from multiple tables
|
### Retrieving Specific Data from Multiple Tables
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
Book
|
Book
|
||||||
|
|
|
@ -1020,7 +1020,7 @@ conditions in a shorter way.
|
||||||
validates :password, confirmation: true, unless: -> { password.blank? }
|
validates :password, confirmation: true, unless: -> { password.blank? }
|
||||||
```
|
```
|
||||||
|
|
||||||
### Grouping Conditional validations
|
### Grouping Conditional Validations
|
||||||
|
|
||||||
Sometimes it is useful to have multiple validations use one condition. It can
|
Sometimes it is useful to have multiple validations use one condition. It can
|
||||||
be easily achieved using [`with_options`][].
|
be easily achieved using [`with_options`][].
|
||||||
|
@ -1228,7 +1228,7 @@ irb> person.errors[:name]
|
||||||
=> ["can't be blank", "is too short (minimum is 3 characters)"]
|
=> ["can't be blank", "is too short (minimum is 3 characters)"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### `errors.where` and error object
|
### `errors.where` and Error Object
|
||||||
|
|
||||||
Sometimes we may need more information about each error beside its message. Each error is encapsulated as an `ActiveModel::Error` object, and [`where`][] method is the most common way of access.
|
Sometimes we may need more information about each error beside its message. Each error is encapsulated as an `ActiveModel::Error` object, and [`where`][] method is the most common way of access.
|
||||||
|
|
||||||
|
|
|
@ -595,7 +595,7 @@ generated URLs are hard to guess, but permanent by design. If your files
|
||||||
require a higher level of protection consider implementing
|
require a higher level of protection consider implementing
|
||||||
[Authenticated Controllers](#authenticated-controllers).
|
[Authenticated Controllers](#authenticated-controllers).
|
||||||
|
|
||||||
### Redirect mode
|
### Redirect Mode
|
||||||
|
|
||||||
To generate a permanent URL for a blob, you can pass the blob to the
|
To generate a permanent URL for a blob, you can pass the blob to the
|
||||||
[`url_for`][ActionView::RoutingUrlFor#url_for] view helper. This generates a
|
[`url_for`][ActionView::RoutingUrlFor#url_for] view helper. This generates a
|
||||||
|
@ -633,7 +633,7 @@ Rails.application.routes.url_helpers.rails_blob_path(user.avatar, only_path: tru
|
||||||
[ActionView::RoutingUrlFor#url_for]: https://api.rubyonrails.org/classes/ActionView/RoutingUrlFor.html#method-i-url_for
|
[ActionView::RoutingUrlFor#url_for]: https://api.rubyonrails.org/classes/ActionView/RoutingUrlFor.html#method-i-url_for
|
||||||
[ActiveStorage::Blob#signed_id]: https://api.rubyonrails.org/classes/ActiveStorage/Blob.html#method-i-signed_id
|
[ActiveStorage::Blob#signed_id]: https://api.rubyonrails.org/classes/ActiveStorage/Blob.html#method-i-signed_id
|
||||||
|
|
||||||
### Proxy mode
|
### Proxy Mode
|
||||||
|
|
||||||
Optionally, files can be proxied instead. This means that your application servers will download file data from the storage service in response to requests. This can be useful for serving files from a CDN.
|
Optionally, files can be proxied instead. This means that your application servers will download file data from the storage service in response to requests. This can be useful for serving files from a CDN.
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ Or if you want to explicitly proxy specific attachments there are URL helpers yo
|
||||||
<%= image_tag rails_storage_proxy_path(@user.avatar) %>
|
<%= image_tag rails_storage_proxy_path(@user.avatar) %>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Putting a CDN in front of Active Storage
|
#### Putting a CDN in Front of Active Storage
|
||||||
|
|
||||||
Additionally, in order to use a CDN for Active Storage attachments, you will need to generate URLs with proxy mode so that they are served by your app and the CDN will cache the attachment without any extra configuration. This works out of the box because the default Active Storage proxy controller sets an HTTP header indicating to the CDN to cache the response.
|
Additionally, in order to use a CDN for Active Storage attachments, you will need to generate URLs with proxy mode so that they are served by your app and the CDN will cache the attachment without any extra configuration. This works out of the box because the default Active Storage proxy controller sets an HTTP header indicating to the CDN to cache the response.
|
||||||
|
|
||||||
|
@ -969,7 +969,7 @@ directly from the client to the cloud.
|
||||||
|
|
||||||
4. That's it! Uploads begin upon form submission.
|
4. That's it! Uploads begin upon form submission.
|
||||||
|
|
||||||
### Cross-Origin Resource Sharing (CORS) configuration
|
### Cross-Origin Resource Sharing (CORS) Configuration
|
||||||
|
|
||||||
To make direct uploads to a third-party service work, you’ll need to configure the service to allow cross-origin requests from your app. Consult the CORS documentation for your service:
|
To make direct uploads to a third-party service work, you’ll need to configure the service to allow cross-origin requests from your app. Consult the CORS documentation for your service:
|
||||||
|
|
||||||
|
@ -992,7 +992,7 @@ Take care to allow:
|
||||||
|
|
||||||
No CORS configuration is required for the Disk service since it shares your app’s origin.
|
No CORS configuration is required for the Disk service since it shares your app’s origin.
|
||||||
|
|
||||||
#### Example: S3 CORS configuration
|
#### Example: S3 CORS Configuration
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
|
@ -1017,7 +1017,7 @@ No CORS configuration is required for the Disk service since it shares your app
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example: Google Cloud Storage CORS configuration
|
#### Example: Google Cloud Storage CORS Configuration
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
|
@ -1030,7 +1030,7 @@ No CORS configuration is required for the Disk service since it shares your app
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example: Azure Storage CORS configuration
|
#### Example: Azure Storage CORS Configuration
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<Cors>
|
<Cors>
|
||||||
|
@ -1043,7 +1043,7 @@ No CORS configuration is required for the Disk service since it shares your app
|
||||||
</Cors>
|
</Cors>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Direct upload JavaScript events
|
### Direct Upload JavaScript Events
|
||||||
|
|
||||||
| Event name | Event target | Event data (`event.detail`) | Description |
|
| Event name | Event target | Event data (`event.detail`) | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
|
@ -1261,9 +1261,9 @@ end
|
||||||
|
|
||||||
[`fixture_file_upload`]: https://api.rubyonrails.org/classes/ActionDispatch/TestProcess/FixtureFile.html
|
[`fixture_file_upload`]: https://api.rubyonrails.org/classes/ActionDispatch/TestProcess/FixtureFile.html
|
||||||
|
|
||||||
### Discarding files created during tests
|
### Discarding Files Created During Tests
|
||||||
|
|
||||||
#### System tests
|
#### System Tests
|
||||||
|
|
||||||
System tests clean up test data by rolling back a transaction. Because `destroy`
|
System tests clean up test data by rolling back a transaction. Because `destroy`
|
||||||
is never called on an object, the attached files are never cleaned up. If you
|
is never called on an object, the attached files are never cleaned up. If you
|
||||||
|
@ -1307,7 +1307,7 @@ config.active_job.queue_adapter = :inline
|
||||||
|
|
||||||
[parallel tests]: testing.html#parallel-testing
|
[parallel tests]: testing.html#parallel-testing
|
||||||
|
|
||||||
#### Integration tests
|
#### Integration Tests
|
||||||
|
|
||||||
Similarly to System Tests, files uploaded during Integration Tests will not be
|
Similarly to System Tests, files uploaded during Integration Tests will not be
|
||||||
automatically cleaned up. If you want to clear the files, you can do it in an
|
automatically cleaned up. If you want to clear the files, you can do it in an
|
||||||
|
@ -1336,7 +1336,7 @@ end
|
||||||
|
|
||||||
[parallel tests]: testing.html#parallel-testing
|
[parallel tests]: testing.html#parallel-testing
|
||||||
|
|
||||||
### Adding attachments to fixtures
|
### Adding Attachments to Fixtures
|
||||||
|
|
||||||
You can add attachments to your existing [fixtures][]. First, you'll want to create a separate storage service:
|
You can add attachments to your existing [fixtures][]. First, you'll want to create a separate storage service:
|
||||||
|
|
||||||
|
@ -1384,7 +1384,7 @@ class UserTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Cleaning up fixtures
|
#### Cleaning up Fixtures
|
||||||
|
|
||||||
While files uploaded in tests are cleaned up [at the end of each test](#discarding-files-created-during-tests),
|
While files uploaded in tests are cleaned up [at the end of each test](#discarding-files-created-during-tests),
|
||||||
you only need to clean up fixture files once: when all your tests complete.
|
you only need to clean up fixture files once: when all your tests complete.
|
||||||
|
|
|
@ -451,7 +451,7 @@ NOTE: Defined in `active_support/core_ext/object/with_options.rb`.
|
||||||
|
|
||||||
[Object#with_options]: https://api.rubyonrails.org/classes/Object.html#method-i-with_options
|
[Object#with_options]: https://api.rubyonrails.org/classes/Object.html#method-i-with_options
|
||||||
|
|
||||||
### JSON support
|
### JSON Support
|
||||||
|
|
||||||
Active Support provides a better implementation of `to_json` than the `json` gem ordinarily provides for Ruby objects. This is because some classes, like `Hash` and `Process::Status` need special handling in order to provide a proper JSON representation.
|
Active Support provides a better implementation of `to_json` than the `json` gem ordinarily provides for Ruby objects. This is because some classes, like `Hash` and `Process::Status` need special handling in order to provide a proper JSON representation.
|
||||||
|
|
||||||
|
@ -2895,7 +2895,7 @@ NOTE: Defined in `active_support/core_ext/hash/deep_merge.rb`.
|
||||||
[Hash#deep_merge!]: https://api.rubyonrails.org/classes/Hash.html#method-i-deep_merge-21
|
[Hash#deep_merge!]: https://api.rubyonrails.org/classes/Hash.html#method-i-deep_merge-21
|
||||||
[Hash#deep_merge]: https://api.rubyonrails.org/classes/Hash.html#method-i-deep_merge
|
[Hash#deep_merge]: https://api.rubyonrails.org/classes/Hash.html#method-i-deep_merge
|
||||||
|
|
||||||
### Deep duplicating
|
### Deep Duplicating
|
||||||
|
|
||||||
The method [`Hash#deep_dup`][Hash#deep_dup] duplicates itself and all keys and values
|
The method [`Hash#deep_dup`][Hash#deep_dup] duplicates itself and all keys and values
|
||||||
inside recursively with Active Support method `Object#deep_dup`. It works like `Enumerator#each_with_object` with sending `deep_dup` method to each pair inside.
|
inside recursively with Active Support method `Object#deep_dup`. It works like `Enumerator#each_with_object` with sending `deep_dup` method to each pair inside.
|
||||||
|
@ -3235,7 +3235,7 @@ NOTE: Defined in `active_support/core_ext/date/calculations.rb`.
|
||||||
[DateAndTime::Calculations#on_weekend?]: https://api.rubyonrails.org/classes/DateAndTime/Calculations.html#method-i-on_weekend-3F
|
[DateAndTime::Calculations#on_weekend?]: https://api.rubyonrails.org/classes/DateAndTime/Calculations.html#method-i-on_weekend-3F
|
||||||
[DateAndTime::Calculations#past?]: https://api.rubyonrails.org/classes/DateAndTime/Calculations.html#method-i-past-3F
|
[DateAndTime::Calculations#past?]: https://api.rubyonrails.org/classes/DateAndTime/Calculations.html#method-i-past-3F
|
||||||
|
|
||||||
#### Named dates
|
#### Named Dates
|
||||||
|
|
||||||
##### `beginning_of_week`, `end_of_week`
|
##### `beginning_of_week`, `end_of_week`
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ After reading this guide, you will know:
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Introduction to instrumentation
|
Introduction to Instrumentation
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
The instrumentation API provided by Active Support allows developers to provide hooks which other developers may hook into. There are several of these within the [Rails framework](#rails-framework-hooks). With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
|
The instrumentation API provided by Active Support allows developers to provide hooks which other developers may hook into. There are several of these within the [Rails framework](#rails-framework-hooks). With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
|
||||||
|
@ -25,7 +25,7 @@ For example, there is a hook provided within Active Record that is called every
|
||||||
|
|
||||||
You are even able to [create your own events](#creating-custom-events) inside your application which you can later subscribe to.
|
You are even able to [create your own events](#creating-custom-events) inside your application which you can later subscribe to.
|
||||||
|
|
||||||
Subscribing to an event
|
Subscribing to an Event
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Subscribing to an event is easy. Use `ActiveSupport::Notifications.subscribe` with a block to
|
Subscribing to an event is easy. Use `ActiveSupport::Notifications.subscribe` with a block to
|
||||||
|
@ -747,7 +747,7 @@ information about it.
|
||||||
| `:exception` | An array of two elements. Exception class name and the message |
|
| `:exception` | An array of two elements. Exception class name and the message |
|
||||||
| `:exception_object` | The exception object |
|
| `:exception_object` | The exception object |
|
||||||
|
|
||||||
Creating custom events
|
Creating Custom Events
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Adding your own events is easy as well. `ActiveSupport::Notifications` will take care of
|
Adding your own events is easy as well. `ActiveSupport::Notifications` will take care of
|
||||||
|
|
|
@ -131,7 +131,7 @@ If you're building a Rails application that will be an API server first and
|
||||||
foremost, you can start with a more limited subset of Rails and add in features
|
foremost, you can start with a more limited subset of Rails and add in features
|
||||||
as needed.
|
as needed.
|
||||||
|
|
||||||
### Creating a new application
|
### Creating a New Application
|
||||||
|
|
||||||
You can generate a new api Rails app:
|
You can generate a new api Rails app:
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ This will do three main things for you:
|
||||||
- Configure the generators to skip generating views, helpers, and assets when
|
- Configure the generators to skip generating views, helpers, and assets when
|
||||||
you generate a new resource.
|
you generate a new resource.
|
||||||
|
|
||||||
### Changing an existing application
|
### Changing an Existing Application
|
||||||
|
|
||||||
If you want to take an existing application and make it an API one, read the
|
If you want to take an existing application and make it an API one, read the
|
||||||
following steps.
|
following steps.
|
||||||
|
|
|
@ -1050,7 +1050,7 @@ NOTE: You will need an [ExecJS](https://github.com/rails/execjs#readme)
|
||||||
supported runtime in order to use `terser`. If you are using macOS or
|
supported runtime in order to use `terser`. If you are using macOS or
|
||||||
Windows you have a JavaScript runtime installed in your operating system.
|
Windows you have a JavaScript runtime installed in your operating system.
|
||||||
|
|
||||||
### GZipping your assets
|
### GZipping Your Assets
|
||||||
|
|
||||||
By default, gzipped version of compiled assets will be generated, along with
|
By default, gzipped version of compiled assets will be generated, along with
|
||||||
the non-gzipped version of assets. Gzipped assets help reduce the transmission
|
the non-gzipped version of assets. Gzipped assets help reduce the transmission
|
||||||
|
|
|
@ -233,9 +233,9 @@ However, you cannot autoload from the autoload paths, which are managed by the `
|
||||||
|
|
||||||
Why? Initializers only run once, when the application boots. If you reboot the server, they run again in a new process, but reloading does not reboot the server, and initializers don't run again. Let's see the two main use cases.
|
Why? Initializers only run once, when the application boots. If you reboot the server, they run again in a new process, but reloading does not reboot the server, and initializers don't run again. Let's see the two main use cases.
|
||||||
|
|
||||||
### Use case 1: During boot, load reloadable code
|
### Use Case 1: During Boot, Load Reloadable Code
|
||||||
|
|
||||||
#### Autoload on boot and on each reload
|
#### Autoload on Boot and on Each Reload
|
||||||
|
|
||||||
Let's imagine `ApiGateway` is a reloadable class from `app/services` managed by the `main` autoloader and you need to configure its endpoint while the application boots:
|
Let's imagine `ApiGateway` is a reloadable class from `app/services` managed by the `main` autoloader and you need to configure its endpoint while the application boots:
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ end
|
||||||
|
|
||||||
NOTE: For historical reasons, this callback may run twice. The code it executes must be idempotent.
|
NOTE: For historical reasons, this callback may run twice. The code it executes must be idempotent.
|
||||||
|
|
||||||
#### Autoload on boot only
|
#### Autoload on Boot Only
|
||||||
|
|
||||||
Reloadable classes and modules can be autoloaded in `after_initialize` blocks too. These run on boot, but do not run again on reload. In some exceptional cases this may be what you want.
|
Reloadable classes and modules can be autoloaded in `after_initialize` blocks too. These run on boot, but do not run again on reload. In some exceptional cases this may be what you want.
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ Rails.application.config.after_initialize do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
### Use case 2: During boot, load code that remains cached
|
### Use Case 2: During Boot, Load Code that Remains Cached
|
||||||
|
|
||||||
Some configurations take a class or module object, and they store it in a place that is not reloaded.
|
Some configurations take a class or module object, and they store it in a place that is not reloaded.
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ If you want to cache a fragment under certain conditions, you can use
|
||||||
<% end %>
|
<% end %>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Collection caching
|
#### Collection Caching
|
||||||
|
|
||||||
The `render` helper can also cache individual templates rendered for a collection.
|
The `render` helper can also cache individual templates rendered for a collection.
|
||||||
It can even one up the previous example with `each` by reading all cache
|
It can even one up the previous example with `each` by reading all cache
|
||||||
|
@ -189,14 +189,14 @@ render(partial: 'hotels/hotel.html.erb', collection: @hotels, cached: true)
|
||||||
|
|
||||||
Will load a file named `hotels/hotel.html.erb` in any file MIME type, for example you could include this partial in a JavaScript file.
|
Will load a file named `hotels/hotel.html.erb` in any file MIME type, for example you could include this partial in a JavaScript file.
|
||||||
|
|
||||||
### Managing dependencies
|
### Managing Dependencies
|
||||||
|
|
||||||
In order to correctly invalidate the cache, you need to properly define the
|
In order to correctly invalidate the cache, you need to properly define the
|
||||||
caching dependencies. Rails is clever enough to handle common cases so you don't
|
caching dependencies. Rails is clever enough to handle common cases so you don't
|
||||||
have to specify anything. However, sometimes, when you're dealing with custom
|
have to specify anything. However, sometimes, when you're dealing with custom
|
||||||
helpers for instance, you need to explicitly define them.
|
helpers for instance, you need to explicitly define them.
|
||||||
|
|
||||||
#### Implicit dependencies
|
#### Implicit Dependencies
|
||||||
|
|
||||||
Most template dependencies can be derived from calls to `render` in the template
|
Most template dependencies can be derived from calls to `render` in the template
|
||||||
itself. Here are some examples of render calls that `ActionView::Digestor` knows
|
itself. Here are some examples of render calls that `ActionView::Digestor` knows
|
||||||
|
@ -228,7 +228,7 @@ to:
|
||||||
render partial: "documents/document", collection: @project.documents.where(published: true)
|
render partial: "documents/document", collection: @project.documents.where(published: true)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Explicit dependencies
|
#### Explicit Dependencies
|
||||||
|
|
||||||
Sometimes you'll have template dependencies that can't be derived at all. This
|
Sometimes you'll have template dependencies that can't be derived at all. This
|
||||||
is typically the case when rendering happens in helpers. Here's an example:
|
is typically the case when rendering happens in helpers. Here's an example:
|
||||||
|
@ -264,7 +264,7 @@ comment format anywhere in the template, like:
|
||||||
<% end %>
|
<% end %>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### External dependencies
|
#### External Dependencies
|
||||||
|
|
||||||
If you use a helper method, for example, inside a cached block and you then update
|
If you use a helper method, for example, inside a cached block and you then update
|
||||||
that helper, you'll have to bump the cache as well. It doesn't really matter how
|
that helper, you'll have to bump the cache as well. It doesn't really matter how
|
||||||
|
@ -296,7 +296,7 @@ end
|
||||||
|
|
||||||
NOTE: Notice that in this example we used the `cache_key_with_version` method, so the resulting cache key will be something like `products/233-20140225082222765838000/competing_price`. `cache_key_with_version` generates a string based on the model's class name, `id`, and `updated_at` attributes. This is a common convention and has the benefit of invalidating the cache whenever the product is updated. In general, when you use low-level caching, you need to generate a cache key.
|
NOTE: Notice that in this example we used the `cache_key_with_version` method, so the resulting cache key will be something like `products/233-20140225082222765838000/competing_price`. `cache_key_with_version` generates a string based on the model's class name, `id`, and `updated_at` attributes. This is a common convention and has the benefit of invalidating the cache whenever the product is updated. In general, when you use low-level caching, you need to generate a cache key.
|
||||||
|
|
||||||
#### Avoid caching instances of Active Record objects
|
#### Avoid Caching Instances of Active Record Objects
|
||||||
|
|
||||||
Consider this example, which stores a list of Active Record objects representing superusers in the cache:
|
Consider this example, which stores a list of Active Record objects representing superusers in the cache:
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ values with `Rails.cache` and then try to pull them out with the `dalli` gem.
|
||||||
However, you also don't need to worry about exceeding the memcached size limit or
|
However, you also don't need to worry about exceeding the memcached size limit or
|
||||||
violating syntax rules.
|
violating syntax rules.
|
||||||
|
|
||||||
Conditional GET support
|
Conditional GET Support
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache.
|
Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache.
|
||||||
|
|
|
@ -50,11 +50,11 @@ If for whatever reason you find a situation you don't know how to resolve, don't
|
||||||
How to Activate `zeitwerk` Mode
|
How to Activate `zeitwerk` Mode
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
### Applications running Rails 5.x or Less
|
### Applications Running Rails 5.x or Less
|
||||||
|
|
||||||
In applications running a Rails version previous to 6.0, `zeitwerk` mode is not available. You need to be at least in Rails 6.0.
|
In applications running a Rails version previous to 6.0, `zeitwerk` mode is not available. You need to be at least in Rails 6.0.
|
||||||
|
|
||||||
### Applications running Rails 6.x
|
### Applications Running Rails 6.x
|
||||||
|
|
||||||
In applications running Rails 6.x there are two scenarios.
|
In applications running Rails 6.x there are two scenarios.
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ If your application uses `Concerns` as namespace, you have two options:
|
||||||
delete("#{Rails.root}/app/models/concerns")
|
delete("#{Rails.root}/app/models/concerns")
|
||||||
```
|
```
|
||||||
|
|
||||||
### Having `app` in the autoload paths
|
### Having `app` in the Autoload Paths
|
||||||
|
|
||||||
Some projects want something like `app/api/base.rb` to define `API::Base`, and add `app` to the autoload paths to accomplish that.
|
Some projects want something like `app/api/base.rb` to define `API::Base`, and add `app` to the autoload paths to accomplish that.
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ 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.
|
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)
|
### 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
|
In `classic` mode you could technically define several constants at the same top-level and have them all reloaded. For example, given
|
||||||
|
|
||||||
|
@ -426,7 +426,7 @@ Starting with Rails 7, newly generated applications are configured that way by d
|
||||||
|
|
||||||
If your project does not have continuous integration, you can still eager load in the test suite by calling `Rails.application.eager_load!`:
|
If your project does not have continuous integration, you can still eager load in the test suite by calling `Rails.application.eager_load!`:
|
||||||
|
|
||||||
#### minitest
|
#### Minitest
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
@ -450,7 +450,7 @@ RSpec.describe "Zeitwerk compliance" do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
Delete any `require` calls
|
Delete any `require` Calls
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
In my experience, projects generally do not do this. But I've seen a couple, and have heard of a few others.
|
In my experience, projects generally do not do this. But I've seen a couple, and have heard of a few others.
|
||||||
|
@ -468,13 +468,13 @@ Please delete any `require` calls of that type.
|
||||||
New Features You Can Leverage
|
New Features You Can Leverage
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
### Delete `require_dependency` calls
|
### Delete `require_dependency` Calls
|
||||||
|
|
||||||
All known use cases of `require_dependency` have been eliminated with Zeitwerk. You should grep the project and delete them.
|
All known use cases of `require_dependency` have been eliminated with Zeitwerk. You should grep the project and delete them.
|
||||||
|
|
||||||
If your application uses Single Table Inheritance, please see the [Single Table Inheritance section](autoloading_and_reloading_constants.html#single-table-inheritance) of the Autoloading and Reloading Constants (Zeitwerk Mode) guide.
|
If your application uses Single Table Inheritance, please see the [Single Table Inheritance section](autoloading_and_reloading_constants.html#single-table-inheritance) of the Autoloading and Reloading Constants (Zeitwerk Mode) guide.
|
||||||
|
|
||||||
### Qualified Names in Class and Module Definitions Are Now Possible
|
### Qualified Names in Class and Module Definitions are Now Possible
|
||||||
|
|
||||||
You can now robustly use constant paths in class and module definitions:
|
You can now robustly use constant paths in class and module definitions:
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,7 @@ Any modifications you make will be rolled back on exit
|
||||||
irb(main):001:0>
|
irb(main):001:0>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### The app and helper objects
|
#### The `app` and `helper` Objects
|
||||||
|
|
||||||
Inside the `bin/rails console` you have access to the `app` and `helper` instances.
|
Inside the `bin/rails console` you have access to the `app` and `helper` instances.
|
||||||
|
|
||||||
|
|
|
@ -2966,7 +2966,7 @@ NOTE: There is no guarantee that your initializers will run after all the gem
|
||||||
initializers, so any initialization code that depends on a given gem having been
|
initializers, so any initialization code that depends on a given gem having been
|
||||||
initialized should go into a `config.after_initialize` block.
|
initialized should go into a `config.after_initialize` block.
|
||||||
|
|
||||||
Initialization events
|
Initialization Events
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
Rails has 5 initialization events which can be hooked into (listed in the order that they are run):
|
Rails has 5 initialization events which can be hooked into (listed in the order that they are run):
|
||||||
|
@ -3132,7 +3132,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
|
||||||
|
|
||||||
* `disable_dependency_loading`: Disables the automatic dependency loading if the `config.eager_load` is set to `true`.
|
* `disable_dependency_loading`: Disables the automatic dependency loading if the `config.eager_load` is set to `true`.
|
||||||
|
|
||||||
Database pooling
|
Database Pooling
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Active Record database connections are managed by `ActiveRecord::ConnectionAdapters::ConnectionPool` which ensures that a connection pool synchronizes the amount of thread access to a limited number of database connections. This limit defaults to 5 and can be configured in `database.yml`.
|
Active Record database connections are managed by `ActiveRecord::ConnectionAdapters::ConnectionPool` which ensures that a connection pool synchronizes the amount of thread access to a limited number of database connections. This limit defaults to 5 and can be configured in `database.yml`.
|
||||||
|
@ -3163,7 +3163,7 @@ connection pool by incrementing the `pool` option in `database.yml`
|
||||||
NOTE. If you are running in a multi-threaded environment, there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited number of connections.
|
NOTE. If you are running in a multi-threaded environment, there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited number of connections.
|
||||||
|
|
||||||
|
|
||||||
Custom configuration
|
Custom Configuration
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
You can configure your own code through the Rails configuration object with
|
You can configure your own code through the Rails configuration object with
|
||||||
|
|
|
@ -748,7 +748,7 @@ Ensure the changesets you introduced are included. Fill in some details about
|
||||||
your potential patch, using the pull request template provided. When finished, click "Create
|
your potential patch, using the pull request template provided. When finished, click "Create
|
||||||
pull request".
|
pull request".
|
||||||
|
|
||||||
### Get some Feedback
|
### Get Some Feedback
|
||||||
|
|
||||||
Most pull requests will go through a few iterations before they get merged.
|
Most pull requests will go through a few iterations before they get merged.
|
||||||
Different contributors will sometimes have different opinions, and often
|
Different contributors will sometimes have different opinions, and often
|
||||||
|
|
|
@ -286,7 +286,7 @@ noticeable with large amounts of logging, but it's a good practice to employ.
|
||||||
INFO: This section was written by [Jon Cairns at a StackOverflow answer](https://stackoverflow.com/questions/16546730/logging-in-rails-is-there-any-performance-hit/16546935#16546935)
|
INFO: This section was written by [Jon Cairns at a StackOverflow answer](https://stackoverflow.com/questions/16546730/logging-in-rails-is-there-any-performance-hit/16546935#16546935)
|
||||||
and it is licensed under [cc by-sa 4.0](https://creativecommons.org/licenses/by-sa/4.0/).
|
and it is licensed under [cc by-sa 4.0](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||||
|
|
||||||
Debugging with the `debug` gem
|
Debugging with the `debug` Gem
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
When your code is behaving in unexpected ways, you can try printing to logs or
|
When your code is behaving in unexpected ways, you can try printing to logs or
|
||||||
|
@ -379,7 +379,7 @@ Besides direct evaluation, debugger also helps you collect rich amount of inform
|
||||||
- `backtrace` (or `bt`) - Backtrace (with additional information).
|
- `backtrace` (or `bt`) - Backtrace (with additional information).
|
||||||
- `outline` (or `o`, `ls`) - Available methods, constants, local variables, and instance variables in the current scope.
|
- `outline` (or `o`, `ls`) - Available methods, constants, local variables, and instance variables in the current scope.
|
||||||
|
|
||||||
#### The info command
|
#### The `info` Command
|
||||||
|
|
||||||
It'll give you an overview of the values of local and instance variables that are visible from the current frame.
|
It'll give you an overview of the values of local and instance variables that are visible from the current frame.
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ It'll give you an overview of the values of local and instance variables that ar
|
||||||
@rendered_format = nil
|
@rendered_format = nil
|
||||||
```
|
```
|
||||||
|
|
||||||
#### The backtrace command
|
#### The `backtrace` Command
|
||||||
|
|
||||||
When used without any options, it lists all the frames on the stack:
|
When used without any options, it lists all the frames on the stack:
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ Don't worry, the `backtrace` command provides 2 options to help you filter frame
|
||||||
|
|
||||||
It's also possible to use these options together: `backtrace [num] /pattern/`.
|
It's also possible to use these options together: `backtrace [num] /pattern/`.
|
||||||
|
|
||||||
#### The outline command
|
#### The `outline` Command
|
||||||
|
|
||||||
This command is similar to `pry` and `irb`'s `ls` command. It will show you what's accessible from the current scope, including:
|
This command is similar to `pry` and `irb`'s `ls` command. It will show you what's accessible from the current scope, including:
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ And to remove them, you can use:
|
||||||
- `delete` - delete all breakpoints
|
- `delete` - delete all breakpoints
|
||||||
- `delete <num>` - delete the breakpoint with id `num`
|
- `delete <num>` - delete the breakpoint with id `num`
|
||||||
|
|
||||||
#### The break command
|
#### The `break` Command
|
||||||
|
|
||||||
**Set a breakpoint on a specified line number - e.g. `b 28`**
|
**Set a breakpoint on a specified line number - e.g. `b 28`**
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ Stop by #0 BP - Line /Users/st0012/projects/rails-guide-example/app/controller
|
||||||
Stop by #0 BP - Method @post.save at /Users/st0012/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-7.0.0.alpha2/lib/active_record/suppressor.rb:43
|
Stop by #0 BP - Method @post.save at /Users/st0012/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/activerecord-7.0.0.alpha2/lib/active_record/suppressor.rb:43
|
||||||
```
|
```
|
||||||
|
|
||||||
#### The catch command
|
#### The `catch` Command
|
||||||
|
|
||||||
**Stop when an exception is raised - e.g. `catch ActiveRecord::RecordInvalid`**
|
**Stop when an exception is raised - e.g. `catch ActiveRecord::RecordInvalid`**
|
||||||
|
|
||||||
|
@ -616,7 +616,7 @@ Stop by #0 BP - Method @post.save at /Users/st0012/.rbenv/versions/3.0.1/lib/r
|
||||||
Stop by #1 BP - Catch "ActiveRecord::RecordInvalid"
|
Stop by #1 BP - Catch "ActiveRecord::RecordInvalid"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### The watch command
|
#### The `watch` Command
|
||||||
|
|
||||||
**Stop when the instance variable is changed - e.g. `watch @_response_body`**
|
**Stop when the instance variable is changed - e.g. `watch @_response_body`**
|
||||||
|
|
||||||
|
@ -660,7 +660,7 @@ Stop by #0 BP - Watch #<PostsController:0x00007fce69ca5320> @_response_body =
|
||||||
(rdbg)
|
(rdbg)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Breakpoint options
|
#### Breakpoint Options
|
||||||
|
|
||||||
In addition to different types of breakpoints, you can also specify options to achieve more advanced debugging workflow. Currently, the debugger supports 4 options:
|
In addition to different types of breakpoints, you can also specify options to achieve more advanced debugging workflow. Currently, the debugger supports 4 options:
|
||||||
|
|
||||||
|
@ -705,7 +705,7 @@ Please also note that the first 3 options: `do:`, `pre:` and `if:` are also avai
|
||||||
@rendered_format = nil
|
@rendered_format = nil
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Program your debugging workflow
|
#### Program Your Debugging Workflow
|
||||||
|
|
||||||
With those options, you can script your debugging workflow in one line like:
|
With those options, you can script your debugging workflow in one line like:
|
||||||
|
|
||||||
|
@ -752,7 +752,7 @@ This technique can save you from repeated manual input and make the debugging ex
|
||||||
|
|
||||||
You can find more commands and configuration options from its [documentation](https://github.com/ruby/debug).
|
You can find more commands and configuration options from its [documentation](https://github.com/ruby/debug).
|
||||||
|
|
||||||
Debugging with the `web-console` gem
|
Debugging with the `web-console` Gem
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
Web Console is a bit like `debug`, but it runs in the browser. You can request a console in the context of a view or a controller on any page. The console would be rendered next to your HTML content.
|
Web Console is a bit like `debug`, but it runs in the browser. You can request a console in the context of a view or a controller on any page. The console would be rendered next to your HTML content.
|
||||||
|
|
|
@ -216,7 +216,7 @@ NOTE: Using the Rake task to create the test databases ensures they have the cor
|
||||||
|
|
||||||
If you're using another database, check the file `activerecord/test/config.yml` or `activerecord/test/config.example.yml` for default connection information. You can edit `activerecord/test/config.yml` to provide different credentials on your machine, but you should not push any of those changes back to Rails.
|
If you're using another database, check the file `activerecord/test/config.yml` or `activerecord/test/config.example.yml` for default connection information. You can edit `activerecord/test/config.yml` to provide different credentials on your machine, but you should not push any of those changes back to Rails.
|
||||||
|
|
||||||
### Install JavaScript dependencies
|
### Install JavaScript Dependencies
|
||||||
|
|
||||||
If you installed Yarn, you will need to install the JavaScript dependencies:
|
If you installed Yarn, you will need to install the JavaScript dependencies:
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ If you installed Yarn, you will need to install the JavaScript dependencies:
|
||||||
$ yarn install
|
$ yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installing gem dependencies
|
### Installing Gem Dependencies
|
||||||
|
|
||||||
Gems are installed with [Bundler](https://bundler.io/) which ships by default with Ruby.
|
Gems are installed with [Bundler](https://bundler.io/) which ships by default with Ruby.
|
||||||
|
|
||||||
|
|
|
@ -1098,7 +1098,7 @@ module MyApp
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Reopening existing classes using `class_eval`
|
#### Reopening Existing Classes Using `class_eval`
|
||||||
|
|
||||||
For example, in order to override the engine model
|
For example, in order to override the engine model
|
||||||
|
|
||||||
|
@ -1122,7 +1122,7 @@ end
|
||||||
|
|
||||||
It is very important that the override _reopens_ the class or module. Using the `class` or `module` keywords would define them if they were not already in memory, which would be incorrect because the definition lives in the engine. Using `class_eval` as shown above ensures you are reopening.
|
It is very important that the override _reopens_ the class or module. Using the `class` or `module` keywords would define them if they were not already in memory, which would be incorrect because the definition lives in the engine. Using `class_eval` as shown above ensures you are reopening.
|
||||||
|
|
||||||
#### Reopening existing classes using ActiveSupport::Concern
|
#### Reopening Existing Classes Using ActiveSupport::Concern
|
||||||
|
|
||||||
Using `Class#class_eval` is great for simple adjustments, but for more complex
|
Using `Class#class_eval` is great for simple adjustments, but for more complex
|
||||||
class modifications, you might want to consider using [`ActiveSupport::Concern`]
|
class modifications, you might want to consider using [`ActiveSupport::Concern`]
|
||||||
|
@ -1385,7 +1385,7 @@ Rails code can often be referenced on load of an application. Rails is responsib
|
||||||
|
|
||||||
Load and configuration hooks are the API that allow you to hook into this initialization process without violating the load contract with Rails. This will also mitigate boot performance degradation and avoid conflicts.
|
Load and configuration hooks are the API that allow you to hook into this initialization process without violating the load contract with Rails. This will also mitigate boot performance degradation and avoid conflicts.
|
||||||
|
|
||||||
### Avoid loading Rails Frameworks
|
### Avoid Loading Rails Frameworks
|
||||||
|
|
||||||
Since Ruby is a dynamic language, some code will cause different Rails frameworks to load. Take this snippet for instance:
|
Since Ruby is a dynamic language, some code will cause different Rails frameworks to load. Take this snippet for instance:
|
||||||
|
|
||||||
|
@ -1409,7 +1409,7 @@ This new snippet will only include `MyActiveRecordHelper` when `ActiveRecord::Ba
|
||||||
|
|
||||||
In the Rails framework these hooks are called when a specific library is loaded. For example, when `ActionController::Base` is loaded, the `:action_controller_base` hook is called. This means that all `ActiveSupport.on_load` calls with `:action_controller_base` hooks will be called in the context of `ActionController::Base` (that means `self` will be an `ActionController::Base`).
|
In the Rails framework these hooks are called when a specific library is loaded. For example, when `ActionController::Base` is loaded, the `:action_controller_base` hook is called. This means that all `ActiveSupport.on_load` calls with `:action_controller_base` hooks will be called in the context of `ActionController::Base` (that means `self` will be an `ActionController::Base`).
|
||||||
|
|
||||||
### Modifying Code to use Load Hooks
|
### Modifying Code to Use Load Hooks
|
||||||
|
|
||||||
Modifying code is generally straightforward. If you have a line of code that refers to a Rails framework such as `ActiveRecord::Base` you can wrap that code in a load hook.
|
Modifying code is generally straightforward. If you have a line of code that refers to a Rails framework such as `ActiveRecord::Base` you can wrap that code in a load hook.
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ Note: The Rails error-reporter will always call registered subscribers, regardle
|
||||||
|
|
||||||
There are three ways you can use the error reporter:
|
There are three ways you can use the error reporter:
|
||||||
|
|
||||||
#### Reporting and swallowing errors
|
#### Reporting and Swallowing Errors
|
||||||
[`Rails.error.handle`](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-handle) will report any error raised within the block. It will then **swallow** the error, and the rest of your code outside the block will continue as normal.
|
[`Rails.error.handle`](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-handle) will report any error raised within the block. It will then **swallow** the error, and the rest of your code outside the block will continue as normal.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
|
@ -91,7 +91,7 @@ user = Rails.error.handle(fallback: -> { User.anonymous }) do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Reporting and re-raising errors
|
#### Reporting and Re-raising Errors
|
||||||
[`Rails.error.record`](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-record) will report errors to all registered subscribers and then re-raise the error, meaning that the rest of your code won't execute.
|
[`Rails.error.record`](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-record) will report errors to all registered subscribers and then re-raise the error, meaning that the rest of your code won't execute.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
|
@ -103,7 +103,7 @@ end
|
||||||
|
|
||||||
If no error is raised in the block, `Rails.error.record` will return the result of the block.
|
If no error is raised in the block, `Rails.error.record` will return the result of the block.
|
||||||
|
|
||||||
#### Manually reporting errors
|
#### Manually Reporting Errors
|
||||||
You can also manually report errors by calling [`Rails.error.report`](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-report):
|
You can also manually report errors by calling [`Rails.error.report`](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html#method-i-report):
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
|
@ -116,7 +116,7 @@ end
|
||||||
|
|
||||||
Any options you pass will be passed on the error subscribers.
|
Any options you pass will be passed on the error subscribers.
|
||||||
|
|
||||||
### Error-reporting options
|
### Error-reporting Options
|
||||||
|
|
||||||
All 3 reporting APIs (`#handle`, `#record`, and `#report`) support the following options, which are then passed along to all registered subscribers:
|
All 3 reporting APIs (`#handle`, `#record`, and `#report`) support the following options, which are then passed along to all registered subscribers:
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,7 @@ form_with model: [:admin, :management, @article]
|
||||||
|
|
||||||
For more information on Rails' routing system and the associated conventions, please see [Rails Routing from the Outside In](routing.html) guide.
|
For more information on Rails' routing system and the associated conventions, please see [Rails Routing from the Outside In](routing.html) guide.
|
||||||
|
|
||||||
### How do forms with PATCH, PUT, or DELETE methods work?
|
### How do Forms with PATCH, PUT, or DELETE Methods Work?
|
||||||
|
|
||||||
The Rails framework encourages RESTful design of your applications, which means you'll be making a lot of "PATCH", "PUT", and "DELETE" requests (besides "GET" and "POST"). However, most browsers _don't support_ methods other than "GET" and "POST" when it comes to submitting forms.
|
The Rails framework encourages RESTful design of your applications, which means you'll be making a lot of "PATCH", "PUT", and "DELETE" requests (besides "GET" and "POST"). However, most browsers _don't support_ methods other than "GET" and "POST" when it comes to submitting forms.
|
||||||
|
|
||||||
|
@ -1087,7 +1087,7 @@ As a convenience you can instead pass the symbol `:all_blank` which will create
|
||||||
|
|
||||||
Rather than rendering multiple sets of fields ahead of time you may wish to add them only when a user clicks on an "Add new address" button. Rails does not provide any built-in support for this. When generating new sets of fields you must ensure the key of the associated array is unique - the current JavaScript date (milliseconds since the [epoch](https://en.wikipedia.org/wiki/Unix_time)) is a common choice.
|
Rather than rendering multiple sets of fields ahead of time you may wish to add them only when a user clicks on an "Add new address" button. Rails does not provide any built-in support for this. When generating new sets of fields you must ensure the key of the associated array is unique - the current JavaScript date (milliseconds since the [epoch](https://en.wikipedia.org/wiki/Unix_time)) is a common choice.
|
||||||
|
|
||||||
Using Tag Helpers Without a Form Builder
|
Using Tag Helpers without a Form Builder
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
In case you need to render form fields outside of the context of a form builder, Rails provides tag helpers for common form elements. For example, [`check_box_tag`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-check_box_tag):
|
In case you need to render form fields outside of the context of a form builder, Rails provides tag helpers for common form elements. For example, [`check_box_tag`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-check_box_tag):
|
||||||
|
|
|
@ -196,7 +196,7 @@ Hello, Rails!
|
||||||
To begin with, let's get some text up on screen quickly. To do this, you need to
|
To begin with, let's get some text up on screen quickly. To do this, you need to
|
||||||
get your Rails application server running.
|
get your Rails application server running.
|
||||||
|
|
||||||
### Starting up the Web Server
|
### Starting Up the Web Server
|
||||||
|
|
||||||
You actually have a functional Rails application already. To see it, you need to
|
You actually have a functional Rails application already. To see it, you need to
|
||||||
start a web server on your development machine. You can do this by running the
|
start a web server on your development machine. You can do this by running the
|
||||||
|
|
|
@ -773,7 +773,7 @@ The translation denoted as `:one` is regarded as singular, and the `:other` is u
|
||||||
|
|
||||||
If the lookup for the key does not return a Hash suitable for pluralization, an `I18n::InvalidPluralizationData` exception is raised.
|
If the lookup for the key does not return a Hash suitable for pluralization, an `I18n::InvalidPluralizationData` exception is raised.
|
||||||
|
|
||||||
#### Locale-specific rules
|
#### Locale-specific Rules
|
||||||
|
|
||||||
The I18n gem provides a Pluralization backend that can be used to enable locale-specific rules. Include it
|
The I18n gem provides a Pluralization backend that can be used to enable locale-specific rules. Include it
|
||||||
to the Simple backend, then add the localized pluralization algorithms to translation store, as `i18n.plural.rule`.
|
to the Simple backend, then add the localized pluralization algorithms to translation store, as `i18n.plural.rule`.
|
||||||
|
@ -1112,7 +1112,7 @@ I18n.t :short, scope: [:date, :formats]
|
||||||
|
|
||||||
Generally we recommend using YAML as a format for storing translations. There are cases, though, where you want to store Ruby lambdas as part of your locale data, e.g. for special date formats.
|
Generally we recommend using YAML as a format for storing translations. There are cases, though, where you want to store Ruby lambdas as part of your locale data, e.g. for special date formats.
|
||||||
|
|
||||||
Customize your I18n Setup
|
Customize Your I18n Setup
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
### Using Different Backends
|
### Using Different Backends
|
||||||
|
|
|
@ -248,7 +248,7 @@ render js: "alert('Hello Rails');"
|
||||||
|
|
||||||
This will send the supplied string to the browser with a MIME type of `text/javascript`.
|
This will send the supplied string to the browser with a MIME type of `text/javascript`.
|
||||||
|
|
||||||
#### Rendering raw body
|
#### Rendering Raw Body
|
||||||
|
|
||||||
You can send a raw content back to the browser, without setting any content
|
You can send a raw content back to the browser, without setting any content
|
||||||
type, by using the `:body` option to `render`:
|
type, by using the `:body` option to `render`:
|
||||||
|
@ -264,7 +264,7 @@ time.
|
||||||
NOTE: Unless overridden, your response returned from this render option will be
|
NOTE: Unless overridden, your response returned from this render option will be
|
||||||
`text/plain`, as that is the default content type of Action Dispatch response.
|
`text/plain`, as that is the default content type of Action Dispatch response.
|
||||||
|
|
||||||
#### Rendering raw file
|
#### Rendering Raw File
|
||||||
|
|
||||||
Rails can render a raw file from an absolute path. This is useful for
|
Rails can render a raw file from an absolute path. This is useful for
|
||||||
conditionally rendering static files like error pages.
|
conditionally rendering static files like error pages.
|
||||||
|
@ -281,7 +281,7 @@ since an attacker could use this action to access security sensitive files in yo
|
||||||
|
|
||||||
TIP: `send_file` is often a faster and better option if a layout isn't required.
|
TIP: `send_file` is often a faster and better option if a layout isn't required.
|
||||||
|
|
||||||
#### Rendering objects
|
#### Rendering Objects
|
||||||
|
|
||||||
Rails can render objects responding to `:render_in`.
|
Rails can render objects responding to `:render_in`.
|
||||||
|
|
||||||
|
@ -755,7 +755,7 @@ end
|
||||||
|
|
||||||
This would detect that there are no books with the specified ID, populate the `@books` instance variable with all the books in the model, and then directly render the `index.html.erb` template, returning it to the browser with a flash alert message to tell the user what happened.
|
This would detect that there are no books with the specified ID, populate the `@books` instance variable with all the books in the model, and then directly render the `index.html.erb` template, returning it to the browser with a flash alert message to tell the user what happened.
|
||||||
|
|
||||||
### Using `head` To Build Header-Only Responses
|
### Using `head` to Build Header-Only Responses
|
||||||
|
|
||||||
The [`head`][] method can be used to send responses with only headers to the browser. The `head` method accepts a number or symbol (see [reference table](#the-status-option)) representing an HTTP status code. The options argument is interpreted as a hash of header names and values. For example, you can return only an error header:
|
The [`head`][] method can be used to send responses with only headers to the browser. The `head` method accepts a number or symbol (see [reference table](#the-status-option)) representing an HTTP status code. The options argument is interpreted as a hash of header names and values. For example, you can return only an error header:
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ Setup
|
||||||
Currently, Rails plugins are built as gems, _gemified plugins_. They can be shared across
|
Currently, Rails plugins are built as gems, _gemified plugins_. They can be shared across
|
||||||
different Rails applications using RubyGems and Bundler if desired.
|
different Rails applications using RubyGems and Bundler if desired.
|
||||||
|
|
||||||
### Generate a gemified plugin.
|
### Generate a Gemified Plugin
|
||||||
|
|
||||||
Rails ships with a `rails plugin new` command which creates a
|
Rails ships with a `rails plugin new` command which creates a
|
||||||
skeleton for developing any kind of Rails extension with the ability
|
skeleton for developing any kind of Rails extension with the ability
|
||||||
|
|
|
@ -80,7 +80,7 @@ To find out more about different `rackup` options, you can run:
|
||||||
$ rackup --help
|
$ rackup --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Development and auto-reloading
|
### Development and Auto-reloading
|
||||||
|
|
||||||
Middlewares are loaded once and are not monitored for changes. You will have to restart the server for changes to be reflected in the running application.
|
Middlewares are loaded once and are not monitored for changes. You will have to restart the server for changes to be reflected in the running application.
|
||||||
|
|
||||||
|
|
|
@ -815,7 +815,7 @@ end
|
||||||
|
|
||||||
Both the `matches?` method and the lambda gets the `request` object as an argument.
|
Both the `matches?` method and the lambda gets the `request` object as an argument.
|
||||||
|
|
||||||
#### Constraints in a block form
|
#### Constraints in a Block Form
|
||||||
|
|
||||||
You can specify constraints in a block form. This is useful for when you need to apply the same rule to several routes. For example:
|
You can specify constraints in a block form. This is useful for when you need to apply the same rule to several routes. For example:
|
||||||
|
|
||||||
|
@ -1278,7 +1278,7 @@ video = Video.find_by(identifier: "Roman-Holiday")
|
||||||
edit_video_path(video) # => "/videos/Roman-Holiday/edit"
|
edit_video_path(video) # => "/videos/Roman-Holiday/edit"
|
||||||
```
|
```
|
||||||
|
|
||||||
Breaking up *very* large route file into multiple small ones:
|
Breaking Up *Very* Large Route File into Multiple Small Ones:
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
If you work in a large application with thousands of routes, a single `config/routes.rb` file can become cumbersome and hard to read.
|
If you work in a large application with thousands of routes, a single `config/routes.rb` file can become cumbersome and hard to read.
|
||||||
|
@ -1313,7 +1313,7 @@ You can use the normal routing DSL inside the `admin.rb` routing file, but you *
|
||||||
|
|
||||||
[`draw`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-draw
|
[`draw`]: https://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-draw
|
||||||
|
|
||||||
### Don't use this feature unless you really need it
|
### Don't Use This Feature Unless You Really Need It
|
||||||
|
|
||||||
Having multiple routing files makes discoverability and understandability harder. For most applications - even those with a few hundred routes - it's easier for developers to have a single routing file. The Rails routing DSL already offers a way to break routes in an organized manner with `namespace` and `scope`.
|
Having multiple routing files makes discoverability and understandability harder. For most applications - even those with a few hundred routes - it's easier for developers to have a single routing file. The Rails routing DSL already offers a way to break routes in an organized manner with `namespace` and `scope`.
|
||||||
|
|
||||||
|
|
|
@ -588,7 +588,7 @@ INFO: _Injection is a class of attacks that introduce malicious code or paramete
|
||||||
|
|
||||||
Injection is very tricky, because the same code or parameter can be malicious in one context, but totally harmless in another. A context can be a scripting, query, or programming language, the shell, or a Ruby/Rails method. The following sections will cover all important contexts where injection attacks may happen. The first section, however, covers an architectural decision in connection with Injection.
|
Injection is very tricky, because the same code or parameter can be malicious in one context, but totally harmless in another. A context can be a scripting, query, or programming language, the shell, or a Ruby/Rails method. The following sections will cover all important contexts where injection attacks may happen. The first section, however, covers an architectural decision in connection with Injection.
|
||||||
|
|
||||||
### Permitted lists versus Restricted lists
|
### Permitted Lists Versus Restricted Lists
|
||||||
|
|
||||||
NOTE: _When sanitizing, protecting, or verifying something, prefer permitted lists over restricted lists._
|
NOTE: _When sanitizing, protecting, or verifying something, prefer permitted lists over restricted lists._
|
||||||
|
|
||||||
|
@ -913,7 +913,7 @@ system("/bin/echo","hello; rm *")
|
||||||
# prints "hello; rm *" and does not delete files
|
# prints "hello; rm *" and does not delete files
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Kernel#open's vulnerability
|
#### Kernel#open's Vulnerability
|
||||||
|
|
||||||
`Kernel#open` executes OS command if the argument starts with a vertical bar (`|`).
|
`Kernel#open` executes OS command if the argument starts with a vertical bar (`|`).
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ After reading this guide, you will know:
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Why Write Tests for your Rails Applications?
|
Why Write Tests for Your Rails Applications?
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
Rails makes it super easy to write your tests. It starts by producing skeleton test code while you are creating your models and controllers.
|
Rails makes it super easy to write your tests. It starts by producing skeleton test code while you are creating your models and controllers.
|
||||||
|
@ -62,7 +62,7 @@ Each environment's configuration can be modified similarly. In this case, we can
|
||||||
|
|
||||||
NOTE: Your tests are run under `RAILS_ENV=test`.
|
NOTE: Your tests are run under `RAILS_ENV=test`.
|
||||||
|
|
||||||
### Rails meets Minitest
|
### Rails Meets Minitest
|
||||||
|
|
||||||
If you remember, we used the `bin/rails generate model` command in the
|
If you remember, we used the `bin/rails generate model` command in the
|
||||||
[Getting Started with Rails](getting_started.html) guide. We created our first
|
[Getting Started with Rails](getting_started.html) guide. We created our first
|
||||||
|
@ -141,7 +141,7 @@ An assertion is a line of code that evaluates an object (or expression) for expe
|
||||||
|
|
||||||
Every test may contain one or more assertions, with no restriction as to how many assertions are allowed. Only when all the assertions are successful will the test pass.
|
Every test may contain one or more assertions, with no restriction as to how many assertions are allowed. Only when all the assertions are successful will the test pass.
|
||||||
|
|
||||||
#### Your first failing test
|
#### Your First Failing Test
|
||||||
|
|
||||||
To see how a test failure is reported, you can add a failing test to the `article_test.rb` test case.
|
To see how a test failure is reported, you can add a failing test to the `article_test.rb` test case.
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ By default, every Rails application has three environments: development, test, a
|
||||||
|
|
||||||
A dedicated test database allows you to set up and interact with test data in isolation. This way your tests can mangle test data with confidence, without worrying about the data in the development or production databases.
|
A dedicated test database allows you to set up and interact with test data in isolation. This way your tests can mangle test data with confidence, without worrying about the data in the development or production databases.
|
||||||
|
|
||||||
### Maintaining the test database schema
|
### Maintaining the Test Database Schema
|
||||||
|
|
||||||
In order to run your tests, your test database will need to have the current
|
In order to run your tests, your test database will need to have the current
|
||||||
structure. The test helper checks whether your test database has any pending
|
structure. The test helper checks whether your test database has any pending
|
||||||
|
@ -676,7 +676,7 @@ Notice the `category` key of the `first` Article found in `fixtures/articles.yml
|
||||||
|
|
||||||
NOTE: For associations to reference one another by name, you can use the fixture name instead of specifying the `id:` attribute on the associated fixtures. Rails will auto assign a primary key to be consistent between runs. For more information on this association behavior please read the [Fixtures API documentation](https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
|
NOTE: For associations to reference one another by name, you can use the fixture name instead of specifying the `id:` attribute on the associated fixtures. Rails will auto assign a primary key to be consistent between runs. For more information on this association behavior please read the [Fixtures API documentation](https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
|
||||||
|
|
||||||
#### File attachment fixtures
|
#### File Attachment Fixtures
|
||||||
|
|
||||||
Like other Active Record-backed models, Active Storage attachment records
|
Like other Active Record-backed models, Active Storage attachment records
|
||||||
inherit from ActiveRecord::Base instances and can therefore be populated by
|
inherit from ActiveRecord::Base instances and can therefore be populated by
|
||||||
|
@ -740,7 +740,7 @@ default. Loading involves three steps:
|
||||||
|
|
||||||
TIP: In order to remove existing data from the database, Rails tries to disable referential integrity triggers (like foreign keys and check constraints). If you are getting annoying permission errors on running tests, make sure the database user has privilege to disable these triggers in testing environment. (In PostgreSQL, only superusers can disable all triggers. Read more about PostgreSQL permissions [here](http://blog.endpoint.com/2012/10/postgres-system-triggers-error.html)).
|
TIP: In order to remove existing data from the database, Rails tries to disable referential integrity triggers (like foreign keys and check constraints). If you are getting annoying permission errors on running tests, make sure the database user has privilege to disable these triggers in testing environment. (In PostgreSQL, only superusers can disable all triggers. Read more about PostgreSQL permissions [here](http://blog.endpoint.com/2012/10/postgres-system-triggers-error.html)).
|
||||||
|
|
||||||
#### Fixtures are Active Record objects
|
#### Fixtures are Active Record Objects
|
||||||
|
|
||||||
Fixtures are instances of Active Record. As mentioned in point #3 above, you can access the object directly because it is automatically available as a method whose scope is local of the test case. For example:
|
Fixtures are instances of Active Record. As mentioned in point #3 above, you can access the object directly because it is automatically available as a method whose scope is local of the test case. For example:
|
||||||
|
|
||||||
|
@ -813,7 +813,7 @@ By default, system tests are run with the Selenium driver, using the Chrome
|
||||||
browser, and a screen size of 1400x1400. The next section explains how to
|
browser, and a screen size of 1400x1400. The next section explains how to
|
||||||
change the default settings.
|
change the default settings.
|
||||||
|
|
||||||
### Changing the default settings
|
### Changing the Default Settings
|
||||||
|
|
||||||
Rails makes changing the default settings for system tests very simple. All
|
Rails makes changing the default settings for system tests very simple. All
|
||||||
the setup is abstracted away so you can focus on writing your tests.
|
the setup is abstracted away so you can focus on writing your tests.
|
||||||
|
@ -1008,7 +1008,7 @@ send a POST request to create the new article in the database.
|
||||||
We will be redirected back to the articles index page and there we assert
|
We will be redirected back to the articles index page and there we assert
|
||||||
that the text from the new article's title is on the articles index page.
|
that the text from the new article's title is on the articles index page.
|
||||||
|
|
||||||
#### Testing for multiple screen sizes
|
#### Testing for Multiple Screen Sizes
|
||||||
|
|
||||||
If you want to test for mobile sizes on top of testing for desktop,
|
If you want to test for mobile sizes on top of testing for desktop,
|
||||||
you can create another class that inherits from SystemTestCase and use in your
|
you can create another class that inherits from SystemTestCase and use in your
|
||||||
|
@ -1038,7 +1038,7 @@ class PostsTest < MobileSystemTestCase
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Taking it further
|
#### Taking It Further
|
||||||
|
|
||||||
The beauty of system testing is that it is similar to integration testing in
|
The beauty of system testing is that it is similar to integration testing in
|
||||||
that it tests the user's interaction with your controller, model, and view, but
|
that it tests the user's interaction with your controller, model, and view, but
|
||||||
|
@ -1084,7 +1084,7 @@ When performing requests, we will have [`ActionDispatch::Integration::RequestHel
|
||||||
|
|
||||||
If we need to modify the session, or state of our integration test, take a look at [`ActionDispatch::Integration::Session`](https://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html) to help.
|
If we need to modify the session, or state of our integration test, take a look at [`ActionDispatch::Integration::Session`](https://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html) to help.
|
||||||
|
|
||||||
### Implementing an integration test
|
### Implementing an Integration Test
|
||||||
|
|
||||||
Let's add an integration test to our blog application. We'll start with a basic workflow of creating a new blog article, to verify that everything is working properly.
|
Let's add an integration test to our blog application. We'll start with a basic workflow of creating a new blog article, to verify that everything is working properly.
|
||||||
|
|
||||||
|
@ -1119,7 +1119,7 @@ We will take a look at `assert_select` to query the resulting HTML of a request
|
||||||
|
|
||||||
When we visit our root path, we should see `welcome/index.html.erb` rendered for the view. So this assertion should pass.
|
When we visit our root path, we should see `welcome/index.html.erb` rendered for the view. So this assertion should pass.
|
||||||
|
|
||||||
#### Creating articles integration
|
#### Creating Articles Integration
|
||||||
|
|
||||||
How about testing our ability to create a new article in our blog and see the resulting article.
|
How about testing our ability to create a new article in our blog and see the resulting article.
|
||||||
|
|
||||||
|
@ -1156,7 +1156,7 @@ NOTE: Don't forget to call `follow_redirect!` if you plan to make subsequent req
|
||||||
|
|
||||||
Finally we can assert that our response was successful and our new article is readable on the page.
|
Finally we can assert that our response was successful and our new article is readable on the page.
|
||||||
|
|
||||||
#### Taking it further
|
#### Taking It Further
|
||||||
|
|
||||||
We were able to successfully test a very small workflow for visiting our blog and creating a new article. If we wanted to take this further we could add tests for commenting, removing articles, or editing comments. Integration tests are a great place to experiment with all kinds of use cases for our applications.
|
We were able to successfully test a very small workflow for visiting our blog and creating a new article. If we wanted to take this further we could add tests for commenting, removing articles, or editing comments. Integration tests are a great place to experiment with all kinds of use cases for our applications.
|
||||||
|
|
||||||
|
@ -1166,7 +1166,7 @@ Functional Tests for Your Controllers
|
||||||
|
|
||||||
In Rails, testing the various actions of a controller is a form of writing functional tests. Remember your controllers handle the incoming web requests to your application and eventually respond with a rendered view. When writing functional tests, you are testing how your actions handle the requests and the expected result or response, in some cases an HTML view.
|
In Rails, testing the various actions of a controller is a form of writing functional tests. Remember your controllers handle the incoming web requests to your application and eventually respond with a rendered view. When writing functional tests, you are testing how your actions handle the requests and the expected result or response, in some cases an HTML view.
|
||||||
|
|
||||||
### What to include in your Functional Tests
|
### What to Include in Your Functional Tests
|
||||||
|
|
||||||
You should test for things such as:
|
You should test for things such as:
|
||||||
|
|
||||||
|
@ -1286,7 +1286,7 @@ All of request types have equivalent methods that you can use. In a typical C.R.
|
||||||
|
|
||||||
NOTE: Functional tests do not verify whether the specified request type is accepted by the action, we're more concerned with the result. Request tests exist for this use case to make your tests more purposeful.
|
NOTE: Functional tests do not verify whether the specified request type is accepted by the action, we're more concerned with the result. Request tests exist for this use case to make your tests more purposeful.
|
||||||
|
|
||||||
### Testing XHR (AJAX) requests
|
### Testing XHR (AJAX) Requests
|
||||||
|
|
||||||
To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`,
|
To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`,
|
||||||
`patch`, `put`, and `delete` methods. For example:
|
`patch`, `put`, and `delete` methods. For example:
|
||||||
|
@ -1338,7 +1338,7 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
### Setting Headers and CGI variables
|
### Setting Headers and CGI Variables
|
||||||
|
|
||||||
[HTTP headers](https://tools.ietf.org/search/rfc2616#section-5.3)
|
[HTTP headers](https://tools.ietf.org/search/rfc2616#section-5.3)
|
||||||
and
|
and
|
||||||
|
@ -1353,7 +1353,7 @@ get articles_url, headers: { "Content-Type": "text/plain" } # simulate the reque
|
||||||
get articles_url, headers: { "HTTP_REFERER": "http://example.com/home" } # simulate the request with custom env variable
|
get articles_url, headers: { "HTTP_REFERER": "http://example.com/home" } # simulate the request with custom env variable
|
||||||
```
|
```
|
||||||
|
|
||||||
### Testing `flash` notices
|
### Testing `flash` Notices
|
||||||
|
|
||||||
If you remember from earlier, one of the Three Hashes of the Apocalypse was `flash`.
|
If you remember from earlier, one of the Three Hashes of the Apocalypse was `flash`.
|
||||||
|
|
||||||
|
@ -1426,7 +1426,7 @@ Finished in 0.081972s, 12.1993 runs/s, 48.7972 assertions/s.
|
||||||
1 runs, 4 assertions, 0 failures, 0 errors, 0 skips
|
1 runs, 4 assertions, 0 failures, 0 errors, 0 skips
|
||||||
```
|
```
|
||||||
|
|
||||||
### Putting it together
|
### Putting It Together
|
||||||
|
|
||||||
At this point our Articles controller tests the `:index` as well as `:new` and `:create` actions. What about dealing with existing data?
|
At this point our Articles controller tests the `:index` as well as `:new` and `:create` actions. What about dealing with existing data?
|
||||||
|
|
||||||
|
@ -1516,7 +1516,7 @@ end
|
||||||
|
|
||||||
Similar to other callbacks in Rails, the `setup` and `teardown` methods can also be used by passing a block, lambda, or method name as a symbol to call.
|
Similar to other callbacks in Rails, the `setup` and `teardown` methods can also be used by passing a block, lambda, or method name as a symbol to call.
|
||||||
|
|
||||||
### Test helpers
|
### Test Helpers
|
||||||
|
|
||||||
To avoid code duplication, you can add your own test helpers.
|
To avoid code duplication, you can add your own test helpers.
|
||||||
Sign in helper can be a good example:
|
Sign in helper can be a good example:
|
||||||
|
@ -2113,7 +2113,7 @@ Starting with Rails 7, newly generated applications are configured that way by d
|
||||||
|
|
||||||
If your project does not have continuous integration, you can still eager load in the test suite by calling `Rails.application.eager_load!`:
|
If your project does not have continuous integration, you can still eager load in the test suite by calling `Rails.application.eager_load!`:
|
||||||
|
|
||||||
#### minitest
|
#### Minitest
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
|
@ -45,7 +45,7 @@ The Executor consists of two callbacks: `to_run` and `to_complete`. The Run
|
||||||
callback is called before the application code, and the Complete callback is
|
callback is called before the application code, and the Complete callback is
|
||||||
called after.
|
called after.
|
||||||
|
|
||||||
### Default callbacks
|
### Default Callbacks
|
||||||
|
|
||||||
In a default Rails application, the Executor callbacks are used to:
|
In a default Rails application, the Executor callbacks are used to:
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ directly wrapping code with methods like
|
||||||
`ActiveRecord::Base.connection_pool.with_connection`. The Executor replaces
|
`ActiveRecord::Base.connection_pool.with_connection`. The Executor replaces
|
||||||
these with a single more abstract interface.
|
these with a single more abstract interface.
|
||||||
|
|
||||||
### Wrapping application code
|
### Wrapping Application Code
|
||||||
|
|
||||||
If you're writing a library or component that will invoke application code, you
|
If you're writing a library or component that will invoke application code, you
|
||||||
should wrap it with a call to the executor:
|
should wrap it with a call to the executor:
|
||||||
|
|
|
@ -20,7 +20,7 @@ What Is Webpacker?
|
||||||
|
|
||||||
Webpacker is a Rails wrapper around the [webpack](https://webpack.js.org) build system that provides a standard webpack configuration and reasonable defaults.
|
Webpacker is a Rails wrapper around the [webpack](https://webpack.js.org) build system that provides a standard webpack configuration and reasonable defaults.
|
||||||
|
|
||||||
### What is webpack?
|
### What is Webpack?
|
||||||
|
|
||||||
The goal of webpack, or any front-end build system, is to allow you to write your front-end code in a way that is convenient for developers and then package that code in a way that is convenient for browsers. With webpack, you can manage JavaScript, CSS, and static assets like images or fonts. Webpack will allow you to write your code, reference other code in your application, transform your code, and combine your code into easily downloadable packs.
|
The goal of webpack, or any front-end build system, is to allow you to write your front-end code in a way that is convenient for developers and then package that code in a way that is convenient for browsers. With webpack, you can manage JavaScript, CSS, and static assets like images or fonts. Webpack will allow you to write your code, reference other code in your application, transform your code, and combine your code into easily downloadable packs.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ your JavaScript.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Import maps
|
Import Maps
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
[Import maps](https://github.com/rails/importmap-rails) let you import JavaScript modules using
|
[Import maps](https://github.com/rails/importmap-rails) let you import JavaScript modules using
|
||||||
|
|
Loading…
Reference in New Issue