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
```
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.
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?.
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.
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.
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
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.
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.
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.
`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.
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.
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.
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.
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
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.
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