Given a model with a composite primary key like:
`TravelRoute.primary_key = [:from, :to]`
Calling `TravelRoute.ids` would return an array of identifiers which is
represented by an array of arrays:
```ruby
TravelRoute.all.ids # => [["Ottawa", "New York"], ["London", "Paris"]]
```
Both `ActionText::Record` and `ActionText::RichText` have dedicated `ActiveSupport` load hooks. This adds an
additional hook for `ActionText::EncryptedRichText`, so that external libraries have a similarly simple way
to run code after the subclass is loaded.
With the introduction of composite primary keys, a common usecase is querying for records with tuples representing the composite key. This change introduces new syntax to the where clause that allows specifying an array of columns mapped to a list of corresponding tuples. It converts this to an OR-joined list of separate queries, similar to previous implementations that rely on grouping queries.
Given a model with a composite primary key, for example:
`TravelRoute.primary_key = [:from, :to]`
and two objects of the given model, objects `a` and `b`, should be
equal to each other and have the same `hash` value if they have the same
values for the composite primary key, like:
```ruby
a = TravelRoute.new(from: "NYC", to: "LAX")
b = TravelRoute.new(from: "NYC", to: "LAX")
a == b # => true
a.hash == b.hash # => true
```
At the same time, two objects of the given model should not be equal to
each other and should have different `hash` values if they have
different primary key values or no primary key being set, like:
```ruby
a = TravelRoute.new(from: "NYC", to: "LAX")
b = TravelRoute.new(from: "NYC", to: "SFO")
a == b # => false
a.hash == b.hash # => false
TravelRoute.new == TravelRoute.new # => false
TravelRoute.new.hash == TravelRoute.new.hash # => false
```
Given a `has_many :through` association with `query_constraints`:
```ruby
BlogPost.has_many :posts_tags
BlogPost.has_many :tags,
through: :posts_tags,
query_constraints: [:blog_id, :post_id]
``
It is possible to nullify the association like `blog_post.tags = []`
which results in deletion of records from the `posts_tags` joining table.
In https://github.com/rails/rails/pull/46690 the `db_warnings_action` and `db_warnings_ignore` configs where added. The
`db_warnings_ignore` can take a list of warning messages to match against.
At GitHub we have a subscriber that that does something like this but also filters out error codes. There might also be
other applications that filter via error codes and this could be something they can use instead of just the explicit
messages.
This also refactors the adapter tests in order for mysql2 and postgresql adapters to share the same helper when setting
the db_warnings_action and db_warnings_ignore configs
In asset heavy views, the asset_path helper might be called a lot of
times. When checking the first character of the source element with []
we allocate a string each time just to check it against ?/.
By using String#start_with? we can avoid this step and go a bit faster.
This is the code I used to measure the change:
```
require "bundler/inline"
ROOT_STRING = '/'
TEST_PATH = "/some/path"
gemfile(true) do
source "https://rubygems.org"
gem "benchmark-ips"
end
Benchmark.ips do |x|
x.report("source[0]") do
TEST_PATH[0] != ROOT_STRING
end
x.report("source.start_with?") do
TEST_PATH.start_with?(ROOT_STRING)
end
x.compare!
end
```
Warming up --------------------------------------
source[0] 905.322k i/100ms
source.start_with? 1.541M i/100ms
Calculating -------------------------------------
source[0] 9.012M (± 0.7%) i/s - 45.266M in 5.022969s
source.start_with? 15.395M (± 0.4%) i/s - 77.030M in 5.003691s
Comparison:
source.start_with?: 15394807.0 i/s
source[0]: 9012304.9 i/s - 1.71x slower