We should not need to check defined? here because we are only interested
in whether @html_safe is truthy or falsy.
We can use an aliased attr_reader to make this even faster by skipping
both method dispatch.
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
Previously, BigDecimal was listed as not needing a serializer. However,
when used with an adapter storing the job arguments as JSON, it would get
serialized as a simple String, resulting in deserialization also producing
a String (instead of a BigDecimal).
By using a serializer, we ensure the round trip is safe.
During upgrade deployments of applications with multiple replicas making use of
BigDecimal job arguments with a queue adapter serializing to JSON, there exists
a possible race condition, whereby a "new" replica enqueues a job with an
argument serialized using `BigDecimalSerializer`, and an "old" replica fails to
deserialize it (as it does not have `BigDecimalSerializer`).
Therefore, to ensure safe upgrades, serialization will not use
`BigDecimalSerializer` until `config.active_job.use_big_decimal_serializer` is
enabled, which can be done safely after successful deployment of Rails 7.1.
This option will be removed in Rails 7.2, when it will become the default.
Define API on connection adapter for building a TableDefinition.
The provided TableDefinition object offers insight into what a table
created using the migration method #create_table would look like, including
information on primary keys, column types, etc.
As a part of this PR, we extract TableDefinition#set_primary_key to handle
some of the primary key setting logic currently being performed in #create_table.
The `_dump` task is private so it shouldn't be called by apps. Because
of this were establishing a connection to the db_config twice, once in
`_dump` and once in `dump`. There's no reason to do this since `_dump`
always calls `dump` and apps should not be calling `_dump`.
In Postgres there was an issue when calling `ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity#all_foreign_keys_valid?` if there were multiple schemas with foreign key constraints, because the ALTER TABLE statement did not include the schema.
This commit adds the necessary schema prefix
```
ALTER TABLE [schema].[table_name] VALIDATE CONSTRAINT [constraint]
^^^^^^
```
Previously, named variants could only be used when calling the
`variant` method on an attachment. For files that are not `variable?`
but `previewable?` those pre-defined variants could not be used.
With this patch, the methods `preview` and `representation` also allow
to be passed a variation name as a symbol.
class User < ActiveRecord::Base
has_one_attached :file do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
end
end
<%= image_tag user.file.representation(:thumb) %>
In #45450 we stopped removing connections when establish_connection was
called and an identical connection existed in the pool. Unfortunately
this broke granular connection swapping for the primary_abstract_class
because the class stored in the pool was incorrect.
What was happening was connection for the writing role were getting
stored with the class ActiveRecord::Base and connections for the reading
role were getting ApplicationRecord (or whatever the app set as their
`primary_abstract_class`. If we made sure that the reading connections
also got ActiveRecord::Base that would break granular swapping for both
writing and reading because Active Record doesn't know whether you
wanted global swapping or granular swapping for prevent writes. This bug
only manifests on prevent writes because it's the only value we actually
lookup on the connection pool (because at the point we need it we don't
have access to self).
To fix this I've decided to update the class on the existing pool if it
doesn't match the owner_name passed. This is kind of gross I admit, but
it's safe because the way we find connections is on the
`connection_name`. The class is only stored so that the connection can
find it's `current_preventing_writes` value. This also required me to
move the ivar to an instance method for connection_class on the pool
because we don't want to cache the value and want to make sure we're
getting it from the pool config directly.
MRI has a lot of optimizations for string concatenation that
are only available when concatenating into a `String` instance.
Using a `String` subclass disable these optimizations.
The difference is even more important with YJIT.
So ideally we want the buffer not to be a String subclass.
Luckily, the Action View buffer is for internal use only, so
we can replace inheritance by composition without much work.
Benchmark:
```
ActionView::OutputBuffer: 147644.2 i/s
optimized buffer: 228001.4 i/s - 1.54x (± 0.00) faster
```
Source: https://gist.github.com/casperisfine/7199579a138e268fda71d6a91366af49
NB: That 50% faster figure is to be contextualized, it can radically change
from one template to the other, but is always faster.
The default was changed in c2b96e3 but this test was not updated. Since
the assertion would pass even if the initializer failed, it needs to be
changed to something else.
In an effort to find all the internal callers of `connection_handler` I
decided to remove any uses that are either:
1) Unnecessary - we can call what we need on Base or elsewhere without
going through the handler
2) Incorrect - there's a better way call the same thing. For exmaple
avoiding calling the ivar, and instead calling `send` on an existing
method.
Doing this will inform us what cases the connection handler is required
and how we can expand Base to provide everything an application or gem
could need without going through the handler. Reducing calls makes it
easier to replace or refactor in the future.
Fix: https://github.com/rails/rails/issues/45585
There's no benefit in serializing it as HWIA, it requires
to allow that type for YAML safe_load and takes more space.
We can cast it back to a regular hash before serialization.
It turns out that buildkite CI was running with mysql 8 and that means
we weren't testing the behavior of mysql 5.7. This fixes a failing test
in main due to the difference in error message.