ActiveSupport::Callbacks often ended up with empty Arrays: on callbacks
without a conditional, and on callback sequences which had no before
and/or after callbacks.
Previously, callbacks which were shared with subclasses would not share
between them the procs generated in Filters::Before and Filters::After.
This was also lazily generated so would cause memory growth after an
application is booted (and not sharable between workers via CoW).
This was because we would rebuild the objects used to invoke the
callbacks via CallbackChain#compile, so any difference in the callback
chain would result in all of the callback procs being rebuilt.
This commit changes before and after callbacks (but not around!) to be
shared between all subclasses of where it was defined. This is done by
changing Filters::Before and Filters::After to plain classes which
respond to call instead of generating procs (which wasn't strictly
necessary but was easier to implement, and also results in simpler
objects which use less memory). These objects avoid referencing and tied
to a specific callback sequence and so can be memoized and reused.
This has the most impact on applications with many Controllers, and many
callbacks in the ApplicationController (or similar).
I also took this opportunity to merge together all the different forms
of procs generated (halting, halting_and_conditional, conditional,
simple) into one form with if statements. There isn't any significant
performance benefit from the specialization previously being done.
In `bootstrap.rb` we set the `Rails.logger.level` to `config.log_level`. But at this point, we may have already set up a `BroadcastLogger` with multiple broadcasts that have different levels. So, calling `level=` on the `BroadcastLogger` will overwrite the level of the individual broadcasts. So instead, let's only set the `Rails.logger.level` if the logger is not a `BroadcastLogger`.
This reverts commit df507240dfc83f120a60b8e2e967d5d96663f67b, reversing
changes made to 9f6b721b1d482ab16d7bdce758fea448bd7ffdbb.
Before using any active support core extension, the user must require
`active_support`.
In bensheldon/good_job#1103 it was reported that a connection not
established is being seen when there are multiple configs for an
environment (a multi-db app).
While I think that something is happening where Good Job is accessing
the connection while we're checking for pending migrations, this could
happen in other gems if we're clobbering the connection on
`ActiveRecord::Base` that is needed.
Here we are making a special class to establish connections to the
database. Because the class does not inherit from `Base` and establishes
it's own connection, it won't clobber any existing connections on
`Base`, leaving them in-tact while the app boots.
The reason this wasn't seen in 7.0 is because pending migrations didn't
check all the available configs. Once that was fixed this error
appeared.
I didn't add a test for this because it's really hard to reproduce
without good job and actually booting a server and running a request.
Fixes: #49689
It used to be stdlib but is being extracted in modern rubies.
Overall its usefulness is dubious. In all cases it is included in
Rails, it's only for the `synchronize` method, but end up exposing
a dozen other useless methods.
In the end just using a Mutex is clearer and simpler.
In some cases we can even get away with a single mutex in a constant.
`ActiveRecord::Base` does not (and has never) inherit from
`ActiveModel::Model`.
`ActiveModel::API` was introduced in as an extraction from
`ActiveModel::Model`. At that time (Sep 15, 2021), it was included back
into `ActiveModel::Model`, but was never included in `ActiveRecord` at
all.
The intent communicated around the introduction of `ActiveModel::API`
stated:
> By moving `ActiveModel::Model`'s implementation to a new
> `ActiveModel::API` we keep a definition of the minimum API to talk with
> Action Pack and Action View.
Active Record is also designed to integrate with Action Pack and Action
View. It already does (and its integration predates `ActiveModel::API`
by more than a decade). It's integration is powered by including and
extending the same set of foundational modules, with some
database-specific overrides.
This commit adds an `include ActiveModel::API` statement to
`ActiveRecord::Base`, then re-structures those overrides to comply with
the new module resolution order.
[c477d95]: c477d95604
A new condition was recently [added][1] to exclude error_highlight from
the Gemfile when the Ruby version is 3.2 or greater. However, this
change leads to an extra blank line after `gem "spring"` on Ruby 3.2+.
This could also happen to new apps generated on Rubies < 3.1, but my
guess is that is less common.
This commit fixes the issue by moving the extra blank line into the
condition.
[1]: d7b395145c644434b1c2be07ef334ea5cb643b75
This commit addresses action_controller_gem.rb failure by updating psych as follows.
`$ bundle update psych --conservative`
Refer to https://buildkite.com/rails/rails/builds/100884#018b3a84-f1c5-4461-839c-5cfbe26ee001/1092-1125
- Without this commit
```
$ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
$ cd guides/bug_report_templates
$ ruby action_controller_gem.rb
Fetching gem metadata from https://rubygems.org/...........
... snip ...
Using rails 7.1.1
/home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/runtime.rb:308:in `check_for_activated_spec!': You have already activated psych 5.1.0, but your Gemfile requires psych 5.1.1.1. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/runtime.rb:25:in `block in setup'
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/spec_set.rb:155:in `each'
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/spec_set.rb:155:in `each'
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/runtime.rb:24:in `map'
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/runtime.rb:24:in `setup'
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/inline.rb:66:in `block in gemfile'
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/settings.rb:131:in `temporary'
from /home/yahonda/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bundler-2.3.22/lib/bundler/inline.rb:50:in `gemfile'
from action_controller_gem.rb:5:in `<main>'
$
```
We never explained how migrations paths work for shards. This fixes that
and also adds the appropriate class setup. You no longer need to set a
`default` shard as of #48353. In addition, `ApplicationRecord` should be
used for the non-sharded db that also serves as the tenant/shard router.
Then shards should get their own connection class since the schema
differs.
This refactors the `ActiveRecord::Attributes` module to use
`ActiveModel::AttributeRegistration`. This also replaces the block form
of the `attribute` method (which was support by only Active Record) with
`decorate_attributes` (which is supported by both Active Model and
Active Record). The block form of the `attribute` method was a private
API, so no deprecation is necessary.