Commit Graph

84269 Commits

Author SHA1 Message Date
Gannon McGibbon
5613b1240a Add routes --unused option to detect extraneous routes.
Routes take a long time to draw. Over time, a Rails app can become slow
to boot simply because of how many routes it has. This script can be
used to detect routes that are drawn, but aren't actually valid.
Removing routes this script detects can help speed up your app and
remove dead code.

Example:

```
> bin/rails routes --unused

Found 2 unused routes:

Prefix Verb URI Pattern    Controller#Action
   one GET  /one(.:format) action#one
   two GET  /two(.:format) action#two
```
2022-08-02 20:07:45 -05:00
John Hawthorn
bfa3a5baab
Merge pull request #45699 from jhawthorn/actionview_types_set_constant
Avoid dynamic constant get on SET.symbols
2022-07-29 15:09:03 -07:00
Jonathan Hefner
225cc78885
Merge pull request #45689 from jonathanhefner/encrypted-config-preserve-invalid-yaml
Save encrypted config even if YAML is invalid
2022-07-29 15:47:44 -05:00
Jonathan Hefner
73909f45be
Merge pull request #45688 from jonathanhefner/session-cookies-default-same_site
Fix default `SameSite` for session cookies
2022-07-29 15:46:01 -05:00
Matthew Draper
1adb6170d5 Add changelog entries for #44576 and #44591 2022-07-30 06:09:12 +09:30
Matthew Draper
72cdf1584a
Merge pull request #44591 from rails/defer-db-connect
Simplify adapter construction; defer connect until first use
2022-07-30 06:08:55 +09:30
Matthew Draper
7fe221d898
Merge pull request #44576 from rails/defer-db-verify
Defer verification of database connections
2022-07-30 06:08:34 +09:30
John Hawthorn
845f19a275 Avoid dynamic constant get on SET.symbols
Dynamic constant lookups (ie. x::SOME_CONST) are uncommon and slightly
slow operations (not _that_ slow). We know that the ::SET constant won't
change (this is a private API and it is called only with our own
classes) so we can switch this to an attr_reader for fast access on the
call to delgate_to.

This also removes the unused `type_klass` attr_accessor.
2022-07-29 12:54:40 -07:00
Eileen M. Uchitelle
b623494a29
Merge pull request #45685 from adrianna-chang-shopify/ac-build-create-join-table-definition
Extract `#build_create_join_table_definition`
2022-07-29 13:38:22 -04:00
Eileen M. Uchitelle
214cd77d7f
Merge pull request #45684 from adrianna-chang-shopify/ac-build-change-column-definition
Extract `#build_change_column_definition`
2022-07-29 13:38:06 -04:00
Jonathan Hefner
cefabdff07
Merge pull request #45692 from bhaskarshankarling/fixed-the-delete-comment-guide
fixed the delete comment guide and added missing unless statement [ci-skip]
2022-07-29 10:26:50 -05:00
Matthew Draper
91a3a2d0cc Don't expect rollback to cause a reconnect 2022-07-30 00:55:54 +09:30
Matthew Draper
e4193dee1d Be a bit clearer in the new-adapter-API argument error 2022-07-30 00:55:54 +09:30
Matthew Draper
0223967ab6 Drop default retry count to 1
This is enough to enable basic recovery for everyone by default, while
leaving more time-consuming repeated attempts for those who configure
them.
2022-07-30 00:55:54 +09:30
Matthew Draper
d56188dc7a We're still inside the transaction until the ROLLBACK has run
This previously made no difference, but it now saves us reconnecting to
run a ROLLBACK: because we're still inside a transaction at that moment,
we won't be #restorable?.
2022-07-30 00:55:54 +09:30
Matthew Draper
fe2846a154 Non-retryable exceptions also break connection verification 2022-07-30 00:55:54 +09:30
Matthew Draper
deec3004d8 Configure legacy-API-supplied connection before first use 2022-07-30 00:55:54 +09:30
Matthew Draper
0e9267767f Ensure a lost connection upon COMMIT fails "cleanly"
There's no point attempting to rollback in this case; we can instead
just invalidate the now-lost transaction.

Similarly, even though we can't immediately reconnect for a connection
failure mid-transaction, we can and should drop and prior verification
of the connection: the next out-of-transaction query attempt needs to
fix it, not assume it's working.
2022-07-30 00:55:54 +09:30
Matthew Draper
8551e64e24 Simplify adapter construction; defer connect until first use 2022-07-30 00:55:48 +09:30
Bhaskar Shankarling
8ae17b2afc fixed the delete comment guide and added missing unless statement 2022-07-29 16:35:12 +05:30
Jonathan Hefner
772c462738 Save encrypted config even if YAML is invalid
In #30893, the `credentials:edit` command was changed to prevent saving
invalid YAML:

  ```yaml
  # some_invalid_yaml.yml
  secret_key_base: ...
  - new_key: new value
  ```

  ```console
  $ EDITOR='cp some_invalid_yaml.yml' bin/rails credentials:edit
  ruby-3.1.2/lib/ruby/3.1.0/psych.rb:455:in `parse': (<unknown>): did not find expected key while parsing a block mapping at line 3 column 1 (Psych::SyntaxError)

  $ bin/rails credentials:show
  secret_key_base: ...
  ```

However, throwing away user input is not ideal.  Such behavior can be
particularly troublesome when copying secrets from ephemeral sources.

This commit changes the `credentials:edit` command to always save user
input, and display a helpful warning when saving invalid YAML:

  ```console
  $ EDITOR='cp some_invalid_yaml.yml' bin/rails credentials:edit
  File encrypted and saved.
  WARNING: Invalid YAML in '/path/to/app/config/credentials.yml.enc'.

    (/path/to/app/config/credentials.yml.enc): did not find expected key while parsing a block mapping at line 3 column 1

  Your application will not be able to load 'config/credentials.yml.enc' until the error has been fixed.

  $ bin/rails credentials:show
  # some_invalid_yaml.yml
  secret_key_base: ...
  - new_key: new value
  ```

This commit also applies the same fix to the `encrypted:edit` command.
2022-07-28 16:37:18 -05:00
Jonathan Hefner
752b566152
Merge pull request #45672 from jonathanhefner/generate-master-key-despite-require_master_key
Generate `master.key` even when `require_master_key`
2022-07-28 16:35:24 -05:00
Jonathan Hefner
c95780d7c6 Fix default SameSite for session cookies
Follow-up to #45501.

The Rack base class that `CookieStore` inherits from [always sets
`:same_site`][1].  Thus, `options.key?(:same_site)` always returns true
for session cookies, preventing a default value from being set.

It would be possible to change Rack to conditionally set `:same_site`,
but, from Rack's perspective, it has no reason to not set `:same_site`,
because it treats a `nil` value the same as no value.

Therefore, this commit specifies a default `:same_site` in `CookieStore`,
which simply defers to `request.cookies_same_site_protection` as
`CookieJar` does.

Fixes #45681.

[1]: https://github.com/rack/rack/blob/2.2.4/lib/rack/session/abstract/id.rb#L398-L402
2022-07-28 16:19:21 -05:00
Adrianna Chang
c59cbb55da Define #build_change_column_definition on connection adapters
Define APIs on the MySQL and PostgreSQL connection adapters for building
ChangeColumnDefinition objects. These provide information on what a
column change would look like, when called with the same arguments as
would be passed to #change_column.
2022-07-28 16:15:47 -04:00
Adrianna Chang
108c30e114 Extract build_create_join_table_definition
Exposes an API for building a TableDefinition for a join table operation.
2022-07-28 16:11:47 -04:00
Eileen M. Uchitelle
6d100e540e
Merge pull request #45643 from adrianna-chang-shopify/ac-extract-build-add-col-definition
Extract `#build_add_column_definition`
2022-07-28 15:23:44 -04:00
Adrianna Chang
e91b6421ec Extract #build_add_column_definition
Exposes AlterTable schema definition for adding new columns through new API,
and stores ddl on the schema definition. Refactors existing #add_column method to use
this as an intermediate method to build the create add_column definition.
2022-07-28 15:19:29 -04:00
Eileen M. Uchitelle
f3339dfb95
Merge pull request #45630 from adrianna-chang-shopify/ac-extract-build-create-index-definition
Extract `#build_create_index_definition`
2022-07-28 14:51:32 -04:00
Adrianna Chang
54b45ff8e2 Extract #build_create_index_definition
Exposes CreateIndex schema definition through new API, and stores ddl
on the schema definition. Refactors existing #add_index methods to use
this as an intermediate method to build the create index definition.
2022-07-28 13:42:38 -04:00
Jean Boussier
74a9929ce1
Merge pull request #45679 from Shopify/action-view-no-safe-buffer
Always use an actual Action View buffer to render templates
2022-07-28 14:29:19 +02:00
Jean Boussier
532e39ae01 Always use an actual Action View buffer to render templates
`ActionView::TestCase` would use an `ActiveSupport::SafeBuffer`
which behaves a bit differently. This never happens in production
so it's better to use a more accurate test.
2022-07-28 12:55:58 +02:00
Jean Boussier
b8964e5310
Merge pull request #45678 from Shopify/action-view-fire-erubi-evaluate
Get rid of Erubi#evaluate
2022-07-28 12:35:43 +02:00
Jean Boussier
55756eacbd Get rid of Erubi#evaluate
It's only used by a handful of tests, but having two ways to
evaluate ERB makes it very confusing. The few tests using it can
go through ActionView::Template instead.
2022-07-28 12:16:40 +02:00
Xavier Noria
b712fc9247
Merge pull request #45581 from cantin/autoloading_guide_update
Update autoloading guide for inflection in the once autoloader
2022-07-28 10:45:08 +02:00
Eileen M. Uchitelle
2e8f4cb062
Merge pull request #45669 from adrianna-chang-shopify/ac-allow-change-table-to-specify-base
Allow base for `Table` schema definition to be injected into `#change_table`
2022-07-27 13:58:21 -04:00
Jonathan Hefner
1740b1f2cb Generate master.key even when require_master_key
Prior to this commit, if `config.require_master_key` was set to true in
`config/application.rb`, the `credentials:edit` command could not
automatically generate a master key file:

  ```ruby
  # In config/application.rb
  config.require_master_key = true
  ```

  ```console
  # No previously existing credentials
  $ rm config/master.key config/credentials.yml.enc
  ```

  ```console
  $ bin/rails credentials:edit
  activesupport/lib/active_support/encrypted_file.rb:118:in `handle_missing_key': Missing encryption key to decrypt file with. Ask your team for your master key and write it to config/master.key or put it in the ENV['RAILS_MASTER_KEY']. (ActiveSupport::EncryptedFile::MissingKeyError)
  ```

This commit adds a `EncryptedFile#key?` method that can be used to check
for the existence of a key without raising `MissingKeyError`, and the
`credentials:edit` command now uses this method:

  ```console
  $ bin/rails credentials:edit
  Adding config/master.key to store the encryption key: ...

  Save this in a password manager your team can access.

  If you lose the key, no one, including you, can access anything encrypted with it.

        create  config/master.key
  ```

This commit also applies the same fix to the `encrypted:edit` command.
2022-07-27 11:22:41 -05:00
Jonathan Hefner
1a6cca614e
Merge pull request #45663 from jonathanhefner/encrypted_command-refactor-like-credentials_command
Refactor `EncryptedCommand` a la `CredentialsCommand`
2022-07-27 11:14:13 -05:00
Jean Boussier
e1a2c9e441
Merge pull request #45671 from fatkodima/in_batches-subquery-test
Add missing test ensuring no subqueries for whole table batching
2022-07-27 17:13:23 +02:00
fatkodima
fcd90558b7 Add missing test ensuring no subqueries for whole table batching 2022-07-27 17:37:46 +03:00
Adrianna Chang
1f777620a8 Allow base for Table schema definition to be injected into #change_table 2022-07-27 09:56:47 -04:00
Yasuo Honda
ab325a9209
Merge pull request #45665 from skipkayhil/fix-deprecation-storage-tests
Fix some deprecation warnings in many_test
2022-07-27 13:40:46 +09:00
Hartley McGuire
0a97813328
Fix some deprecation warnings in many_test
The append_on_assign helper function sets
ActiveStorage.replace_on_assign_to_many = false, which is deprecated.
Therefore, any tests using this helper should be using assert_deprecated
to not pollute test output. Some of them were doing this already, but
these two were not.
2022-07-26 22:41:54 -04:00
Gannon McGibbon
8b94e87c11
Merge pull request #45659 from gmcgibbon/parent_option_default
Parent option defaults
2022-07-26 18:35:29 -05:00
Gannon McGibbon
fe199f3d90 Fix typo in controller generator USAGE
Fixes typo introduced in #45627.
2022-07-26 18:13:03 -05:00
Gannon McGibbon
e1635ff4a7 Show default parent classes for generators in help texts
Print default parent class for controller, job, and model generators.

Before:

[--parent=PARENT]               # The parent class for the generated job

After:

[--parent=PARENT]               # The parent class for the generated job
                                # Default: ApplicationJob
2022-07-26 18:13:02 -05:00
Matthew Draper
57bc28f728 Add new tests for deferred connection verification and auto-reconnect 2022-07-27 02:15:15 +09:30
Jean Boussier
b01027fc2f
Merge pull request #45579 from natematykiewicz/touch_records_after_analyze
Touch model records after ActiveStorage::Blob is analyzed
2022-07-26 18:34:18 +02:00
Gannon McGibbon
a28381e1eb
Merge pull request #45661 from gmcgibbon/undef_generator_hook_method
Clean up hook generator method when hook is removed
2022-07-26 11:05:10 -05:00
Jonathan Hefner
ff688a00b0 Refactor EncryptedCommand a la CredentialsCommand
This refactors `EncryptedCommand` and its tests to more closely mirror
`CredentialsCommand`, in preparation for forthcoming shared fixes.

Specifically, `EncryptedCommand` now uses a central
`encrypted_configuration` instance instead of passing arguments around,
and the tests now use a default encrypted file path instead of passing
it around.

This commit also imports tests concerning key file generation from the
`CredentialsCommand` tests.
2022-07-26 10:58:37 -05:00
Nate Matykiewicz
294c271062
Touch model records after ActiveStorage::Blob is analyzed
This fixes a race condition where a record can be requested and have a
cache entry built, before the initial `analyze_later` completes, which
will not be invalidated until something else updates the record.

1. Upload attachment (this will create an ActiveStorage::Blob,
   ActiveStorage::Attachment, and touch the model)
2. Enqueue analyze job
3. Request record
4. Build a cache for that record
5. Analyze the attachment.
6. Request the record again
7. Serve a cache that doesn't include data from the analyzers, because
   the cache was built before it got analyzed, and the updated_at
   hasn't changed.

This also invalidates cache entries when a blob is re-analyzed, which
is helpful if a bug is fixed in an analyzer or a new analyzer is added.

Fixes #45567
2022-07-26 10:39:44 -05:00