We cannot compare paths directly to strings or that might fail on
different operating system. In this case, comparing to `/` fails on
Windows and we end up in endless recursion. We need to use
`Pathname#root?` to check if we reached the root of the folder structure
When an application defines mailers without any corresponding previews,
requests to `GET /rails/mailers` return a page with a blank `<body>`
element.
This entirely empty page can be confusing, since it's difficult to
distinguish the "success" state with an empty list and a "failure" state
with swallowed errors.
Similarly, when an `ActionMailer::Preview` subclass is defined, but
doesn't declare any actions, the response contains a mostly empty page.
This commit renders empty-state messaging for both scenarios, and links
to the [Action Mailer Basics][] guides.
To effectively cover that behavior, this commit also expands the Mailer
Preview test coverage to utilize [rails-dom-testing][] assertions.
[Action Mailer Basics]: https://guides.rubyonrails.org/action_mailer_basics.html#previewing-emails
[rails-dom-testing]: http://github.com/rails/rails-dom-testing
This was originally added in #47781:
> ...rails logo hover on welcome page is being triggered on square instead of round image.
However, on Safari the border is being cut-off.
I'm not sure there is another workaround, but I am willing to accept a larger (square) clickable area to have a consistent drop shadow.
which controls the HTML parser used by rails-dom-testing assertions.
The config parameter is set to :html5 in Rails 7.1 if the Nokogiri
HTML5 parser is supported.
As of Selenium 4.6, [the Selenium Manager is capable of managing Chrome
Driver installations and integrations][readme]. As of Selenium 4.11, the
Selenium Manager is capable of [capable of resolving the Chrome for
Testing installation][] path.
By omitting the `gem` declaration from the `Gemfile.tt`, newly generated
applications and applications updating their `Gemfile` in lockstep with
newer Rails versions can shed the dependency and avoid test failures
introduced by newly released Chrome versions (like, for example,
[titusfortner/webdrivers#247][]).
[readme]: 43f8ac436c (update-selenium-manager)
[titusfortner/webdrivers#247]: https://github.com/titusfortner/webdrivers/issues/247
[capable of resolving the Chrome for Testing installation]: https://github.com/rails/rails/pull/48847#issuecomment-1656756862
Co-authored-by: Titus Fortner <titusfortner@users.noreply.github.com>
This adds additional test coverage to PermissionsPolicy::Middleware to
validate that it conforms to the Rack SPEC.
The only changes necessary were to use the appropriate header casing for
Content-Type and Feature-Policy. Since this was the only usage of the
CONTENT_TYPE constant, I opted to remove it, but I can replace it with a
DeprecatedConstantProxy if that's more desirable.
This commit adds support for replacing the compressor used for
serialized cache entries. Custom compressors must respond to `deflate`
and `inflate`. For example:
```ruby
module MyCompressor
def self.deflate(string)
# compression logic...
end
def self.inflate(compressed)
# decompression logic...
end
end
config.cache_store = :redis_cache_store, { compressor: MyCompressor }
```
As part of this work, cache stores now also support a `:serializer`
option. Similar to the `:coder` option, serializers must respond to
`dump` and `load`. However, serializers are only responsible for
serializing a cached value, whereas coders are responsible for
serializing the entire `ActiveSupport::Cache::Entry` instance.
Additionally, the output from serializers can be automatically
compressed, whereas coders are responsible for their own compression.
Specifying a serializer instead of a coder also enables performance
optimizations, including the bare string optimization introduced by cache
format version 7.1.
The new syntax allows you to filter tests by line ranges. For example, the
following command runs tests between line 10 to 20.
```bash
$ rails test test/models/user_test.rb:10-20
```
Co-authored-by: Seonggi Yang <seonggi.yang@gmail.com>
Co-authored-by: Ryohei UEDA <ueda@anipos.co.jp>
Co-authored-by: oljfte <oljfte@gmail.com>
Followup: https://github.com/rails/rails/pull/48743
After careful consideration, unless users have a schema cache dump loaded
and `check_schema_cache_dump_version = false`, we have no choice but
to arbitrate between resiliency and performance.
If we define attribute methods during boot, we allow them to be shared
between forked workers, and prevent the first requests to be slower.
However, by doing so we'd trigger a connection to the datase, which
if it's unresponsive could lead to workers not being able to restart
triggering a cascading failure.
Previously Rails used to be in some sort of middle-ground where
it would define attribute methods during boot if for some reason
it was already connected to the database at this point.
But this is now deemed undesirable, as an application initializer
inadvertantly establishing the database connection woudl lead to
a readically different behavior.
Followup: https://github.com/rails/rails/pull/48716
`model.connection_pool.schema_reflection` is never falsy, so that `if`
was pointless.
Instead we more properly check if the schema cache contains that table.
I also added some more comments to explain why the initializer tries
so hard not to touch the database.
A big problem with the current `SchemaCache` implementation is that it holds
a reference to a connection, and uses it to lazily query the schema when the
information is missing.
This cause issues in multi-threaded contexts because all the connections
of a pool share the same schema, so they are constantly setting themselves
as the connection the schema cache should use, and you can end up in
situation where Thread#1 query the schema cache, which end up using the
connection currently attributed to Thread#2.
For a very long time this worked more or less by accident, because all
connection adapters would have an internal Monitor.
However in https://github.com/rails/rails/pull/46519 we got rid of this
synchronization, revealing the pre-existing issue. Previously it would
work™, but still wasn't ideal because of unexpected the connection
sharing between threads.
The idea here is to refactor the schema cache so that it doesn't hold a
reference onto any connection.
And instead of a `SchemaCache`, connections now have access to a
`SchemaReflection`. Now the connection that needs a schema information
is always provided as an argument, so that in case of a miss, it can be
used to populate the cache.
That should fix the database thread safety issues that were witnessed.
However note that at this stage, the underlying `SchemaCache` isn't
synchronized, so in case of a race condition, the same schema query
can be performed more than once. It could make sense to add synchronization
in a followup.
This refactoring also open the door to query the cache without a connection,
making it easier to eagerly define model attribute methods on boot without
establishing a connection to the database.
Co-Authored-By: Jean Boussier <jean.boussier@gmail.com>
Co-Authored-By: zzak <zzakscott@gmail.com>
Fix: https://github.com/rails/rails/issues/45017
Ref: https://github.com/rails/rails/pull/29333
Ref: https://github.com/ruby/timeout/pull/30
Historically only raised errors would trigger a rollback, but in Ruby `2.3`, the `timeout` library
started using `throw` to interupt execution which had the adverse effect of committing open transactions.
To solve this, in Active Record 6.1 the behavior was changed to instead rollback the transaction as it was safer
than to potentially commit an incomplete transaction.
Using `return`, `break` or `throw` inside a `transaction` block was essentially deprecated from Rails 6.1 onwards.
However with the release of `timeout 0.4.0`, `Timeout.timeout` now raises an error again, and Active Record is able
to return to its original, less surprising, behavior.
This test uses sqlite3 in production mode which results in a warning in
the test output. This change sets the config option for silencing this
warning so we don't see it in test output.
Fixes 2 bugs in parallel testing.
The first bug was related to changes made in #45450 which meant that we were
no longer replacing the connection in parallel testing because the
config object is equal (we simply merge a new db name but the object id
of the config stays the same). This bug only manifested in mysql and
sqlite3 interestingly. It would fail on the internal metadata tables
because they were missing in the schema version check.
To fix this I introduced a `clobber: true` kwarg onto the connection
handler that allows us to bypass the functionality that won't make a new
connection if the config is the same. This is an easy way to fall back
to the old behavior from before this change. I only added `clobber`
to the `reconstruct_from_schema` call because we need to actually
replace the connection for these. It's not safe to add everywhere since
we don't always want to replace the connection.
After implementing this fix I was still seeing failures in the mysql
demo app I made due to the fact that `purge` was not re-establishing the
connection to a config that had a database defined. Neither sqlite3 or
postgresql were missing this.
I added a test for mysql2 so we don't have regressions in the future. I
think this was missed because sqlite3 only demonstrates the bug if it
was never successful on that worker and postgresql was fine.
Fixes#48547
Fixes#48398
Prepared Statements and Query Logs are incompatible features due to query logs making every query unique.
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
XHR requests other than GET or POST have issues when using 302
(e.g browsers trying to follow the redirect using the
original request method resulting in double PATCH/PUT)
This should be reverted when / if
https://github.com/rails/rails/pull/45393 is merged
A deprecation warning was [added][1] to ensure that applications
manually setting `config.active_support.cache_format_version` to `6.1`
will be aware that they need to migrate. However, if an app is not using
a `config.load_defaults` of `7.0` or greater, this warning will never be
triggered.
This commit moves the deprecation warning to where the `cache_format`
value gets used to cover both cases.
[1]: 2ba3ac29c36f4c6d23b1dd302584f15739ff2aff
This middleware has been logging at a FATAL level since the first
[commit][1] in Rails (the code originally lived in
actionpack/lib/action_controller/rescue.rb). However, FATAL is
documented in the Ruby Logger [docs][2] as being for "An unhandleable
error that results in a program crash.", which does not really apply to
this case since DebugExceptions is handling the error. A more
appropriate level would be ERROR, which the Ruby Logger docs describe as
"A handleable error condition."
This commit introduces a new configuration for the DebugExceptions log
level so that new apps will have it set to ERROR by default and ERROR
can eventually be made the default.
[1]: db045dbbf60b53dbe013ef25554fd013baf88134
[2]: https://ruby-doc.org/3.2.1/stdlibs/logger/Logger/Severity.html
* Make sure active record encryption configuration happens after initializers have run
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
* Add a new option to support previous data encrypted non-deterministically with a hash digest of SHA1
There is currently a problem with Active Record encryption for users updating from 7.0 to 7.1 Before
#44873, data encrypted with non-deterministic encryption was always using SHA-1. The reason is that
`ActiveSupport::KeyGenerator.hash_digest_class` is set in an after_initialize block in the railtie config,
but encryption config was running before that, so it was effectively using the previous default SHA1. That
means that existing users are using SHA256 for non deterministic encryption, and SHA1 for deterministic
encryption.
This adds a new option `use_sha1_digest_for_non_deterministic_data` that
users can enable to support for SHA1 and SHA256 when decrypting existing data.
* Set a default value of true for `support_sha1_for_non_deterministic_encryption` and proper initializer values.
We want to enable the flag existing versions (< 7.1), and we want it to be false moving by
default moving forward.
* Make sure the system to auto-filter params supports different initialization orders
This reworks the system to auto-filter params so that it works when encrypted
attributes are declared before the encryption configuration logic runs.
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
---------
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
For local environments (def and test), we create a secret file. However this file is called development_secret.txt, which imho is confusing as it is used by both dev and test environments.
This commit renames the file and related code to local_secret.
When calling `Rails.application.config#inspect` it will show all
attributes, including @secret_key_base after 21c34550549ed90f79565b333e06c7cee79c546e
By overriding the `inspect` method to only show the class name we can
avoid accidentally outputting sensitive information.
Before:
```ruby
Rails.application.config.inspect
"#<Rails::Application::Configuration:0x00000001132b02a0 @root=... @secret_key_base=\"b3c631c314c0bbca50c1b2843150fe33\" ... >"
```
After:
```ruby
Rails.application.config.inspect
"#<Rails::Application::Configuration:0x00000001132b02a0>"
```
Rails `secrets` have been deprecated in favor of `credentials`.
For the local environment the `secret_key_base` is now be stored in
`Rails.config.secret_key_base` instead of the deprecated
`Rails.application.secrets.secret_key_base`.